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);
85 #ifdef CONFIG_MTD_PARTITIONS
86 const char *part_probes
[] = { "cmdlinepart", NULL
};
90 * Probe for the NAND device.
92 static int __init
at91_nand_probe(struct platform_device
*pdev
)
94 struct at91_nand_host
*host
;
96 struct nand_chip
*nand_chip
;
99 #ifdef CONFIG_MTD_PARTITIONS
100 struct mtd_partition
*partitions
= NULL
;
101 int num_partitions
= 0;
104 /* Allocate memory for the device structure (and zero it) */
105 host
= kzalloc(sizeof(struct at91_nand_host
), GFP_KERNEL
);
107 printk(KERN_ERR
"at91_nand: failed to allocate device structure.\n");
111 host
->io_base
= ioremap(pdev
->resource
[0].start
,
112 pdev
->resource
[0].end
- pdev
->resource
[0].start
+ 1);
113 if (host
->io_base
== NULL
) {
114 printk(KERN_ERR
"at91_nand: ioremap failed\n");
120 nand_chip
= &host
->nand_chip
;
121 host
->board
= pdev
->dev
.platform_data
;
123 nand_chip
->priv
= host
; /* link the private data structures */
124 mtd
->priv
= nand_chip
;
125 mtd
->owner
= THIS_MODULE
;
127 /* Set address of NAND IO lines */
128 nand_chip
->IO_ADDR_R
= host
->io_base
;
129 nand_chip
->IO_ADDR_W
= host
->io_base
;
130 nand_chip
->cmd_ctrl
= at91_nand_cmd_ctrl
;
132 if (host
->board
->rdy_pin
)
133 nand_chip
->dev_ready
= at91_nand_device_ready
;
135 nand_chip
->ecc
.mode
= NAND_ECC_SOFT
; /* enable ECC */
136 nand_chip
->chip_delay
= 20; /* 20us command delay time */
138 if (host
->board
->bus_width_16
) /* 16-bit bus width */
139 nand_chip
->options
|= NAND_BUSWIDTH_16
;
141 platform_set_drvdata(pdev
, host
);
142 at91_nand_enable(host
);
144 if (host
->board
->det_pin
) {
145 if (at91_get_gpio_value(host
->board
->det_pin
)) {
146 printk ("No SmartMedia card inserted.\n");
152 /* Scan to find existance of the device */
153 if (nand_scan(mtd
, 1)) {
158 #ifdef CONFIG_MTD_PARTITIONS
159 if (host
->board
->partition_info
)
160 partitions
= host
->board
->partition_info(mtd
->size
, &num_partitions
);
161 #ifdef CONFIG_MTD_CMDLINE_PARTS
163 mtd
->name
= "at91_nand";
164 num_partitions
= parse_mtd_partitions(mtd
, part_probes
, &partitions
, 0);
168 if ((!partitions
) || (num_partitions
== 0)) {
169 printk(KERN_ERR
"at91_nand: No parititions defined, or unsupported device.\n");
174 res
= add_mtd_partitions(mtd
, partitions
, num_partitions
);
176 res
= add_mtd_device(mtd
);
185 at91_nand_disable(host
);
186 platform_set_drvdata(pdev
, NULL
);
187 iounmap(host
->io_base
);
193 * Remove a NAND device.
195 static int __devexit
at91_nand_remove(struct platform_device
*pdev
)
197 struct at91_nand_host
*host
= platform_get_drvdata(pdev
);
198 struct mtd_info
*mtd
= &host
->mtd
;
202 at91_nand_disable(host
);
204 iounmap(host
->io_base
);
210 static struct platform_driver at91_nand_driver
= {
211 .probe
= at91_nand_probe
,
212 .remove
= at91_nand_remove
,
215 .owner
= THIS_MODULE
,
219 static int __init
at91_nand_init(void)
221 return platform_driver_register(&at91_nand_driver
);
225 static void __exit
at91_nand_exit(void)
227 platform_driver_unregister(&at91_nand_driver
);
231 module_init(at91_nand_init
);
232 module_exit(at91_nand_exit
);
234 MODULE_LICENSE("GPL");
235 MODULE_AUTHOR("Rick Bronson");
236 MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200");