2 * drivers/mtd/nand/at91_nand.c
4 * Copyright (C) 2003 Rick Bronson
6 * Derived from drivers/mtd/nand/autcpu12.c
7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
9 * Derived from drivers/mtd/spia.c
10 * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
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.
18 #include <linux/slab.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/mtd/mtd.h>
22 #include <linux/mtd/nand.h>
23 #include <linux/mtd/partitions.h>
26 #include <asm/sizes.h>
28 #include <asm/hardware.h>
29 #include <asm/arch/board.h>
30 #include <asm/arch/gpio.h>
32 struct at91_nand_host
{
33 struct nand_chip nand_chip
;
35 void __iomem
*io_base
;
36 struct at91_nand_data
*board
;
40 * Hardware specific access to control-lines
42 static void at91_nand_cmd_ctrl(struct mtd_info
*mtd
, int cmd
, unsigned int ctrl
)
44 struct nand_chip
*nand_chip
= mtd
->priv
;
45 struct at91_nand_host
*host
= nand_chip
->priv
;
47 if (cmd
== NAND_CMD_NONE
)
51 writeb(cmd
, host
->io_base
+ (1 << host
->board
->cle
));
53 writeb(cmd
, host
->io_base
+ (1 << host
->board
->ale
));
57 * Read the Device Ready pin.
59 static int at91_nand_device_ready(struct mtd_info
*mtd
)
61 struct nand_chip
*nand_chip
= mtd
->priv
;
62 struct at91_nand_host
*host
= nand_chip
->priv
;
64 return at91_get_gpio_value(host
->board
->rdy_pin
);
70 static void at91_nand_enable(struct at91_nand_host
*host
)
72 if (host
->board
->enable_pin
)
73 at91_set_gpio_value(host
->board
->enable_pin
, 0);
79 static void at91_nand_disable(struct at91_nand_host
*host
)
81 if (host
->board
->enable_pin
)
82 at91_set_gpio_value(host
->board
->enable_pin
, 1);
86 * Probe for the NAND device.
88 static int __init
at91_nand_probe(struct platform_device
*pdev
)
90 struct at91_nand_host
*host
;
92 struct nand_chip
*nand_chip
;
95 #ifdef CONFIG_MTD_PARTITIONS
96 struct mtd_partition
*partitions
= NULL
;
97 int num_partitions
= 0;
100 /* Allocate memory for the device structure (and zero it) */
101 host
= kzalloc(sizeof(struct at91_nand_host
), GFP_KERNEL
);
103 printk(KERN_ERR
"at91_nand: failed to allocate device structure.\n");
107 host
->io_base
= ioremap(pdev
->resource
[0].start
,
108 pdev
->resource
[0].end
- pdev
->resource
[0].start
+ 1);
109 if (host
->io_base
== NULL
) {
110 printk(KERN_ERR
"at91_nand: ioremap failed\n");
116 nand_chip
= &host
->nand_chip
;
117 host
->board
= pdev
->dev
.platform_data
;
119 nand_chip
->priv
= host
; /* link the private data structures */
120 mtd
->priv
= nand_chip
;
121 mtd
->owner
= THIS_MODULE
;
123 /* Set address of NAND IO lines */
124 nand_chip
->IO_ADDR_R
= host
->io_base
;
125 nand_chip
->IO_ADDR_W
= host
->io_base
;
126 nand_chip
->cmd_ctrl
= at91_nand_cmd_ctrl
;
127 nand_chip
->dev_ready
= at91_nand_device_ready
;
128 nand_chip
->ecc
.mode
= NAND_ECC_SOFT
; /* enable ECC */
129 nand_chip
->chip_delay
= 20; /* 20us command delay time */
131 if (host
->board
->bus_width_16
) /* 16-bit bus width */
132 nand_chip
->options
|= NAND_BUSWIDTH_16
;
134 platform_set_drvdata(pdev
, host
);
135 at91_nand_enable(host
);
137 if (host
->board
->det_pin
) {
138 if (at91_get_gpio_value(host
->board
->det_pin
)) {
139 printk ("No SmartMedia card inserted.\n");
145 /* Scan to find existance of the device */
146 if (nand_scan(mtd
, 1)) {
151 #ifdef CONFIG_MTD_PARTITIONS
152 if (host
->board
->partition_info
)
153 partitions
= host
->board
->partition_info(mtd
->size
, &num_partitions
);
155 if ((!partitions
) || (num_partitions
== 0)) {
156 printk(KERN_ERR
"at91_nand: No parititions defined, or unsupported device.\n");
161 res
= add_mtd_partitions(mtd
, partitions
, num_partitions
);
163 res
= add_mtd_device(mtd
);
172 at91_nand_disable(host
);
173 platform_set_drvdata(pdev
, NULL
);
174 iounmap(host
->io_base
);
180 * Remove a NAND device.
182 static int __devexit
at91_nand_remove(struct platform_device
*pdev
)
184 struct at91_nand_host
*host
= platform_get_drvdata(pdev
);
185 struct mtd_info
*mtd
= &host
->mtd
;
189 at91_nand_disable(host
);
191 iounmap(host
->io_base
);
197 static struct platform_driver at91_nand_driver
= {
198 .probe
= at91_nand_probe
,
199 .remove
= at91_nand_remove
,
202 .owner
= THIS_MODULE
,
206 static int __init
at91_nand_init(void)
208 return platform_driver_register(&at91_nand_driver
);
212 static void __exit
at91_nand_exit(void)
214 platform_driver_unregister(&at91_nand_driver
);
218 module_init(at91_nand_init
);
219 module_exit(at91_nand_exit
);
221 MODULE_LICENSE("GPL");
222 MODULE_AUTHOR("Rick Bronson");
223 MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200");