diff options
Diffstat (limited to 'drivers/mtd/nand/autcpu12.c')
-rw-r--r-- | drivers/mtd/nand/autcpu12.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c new file mode 100644 index 000000000000..4afa8ced05ad --- /dev/null +++ b/drivers/mtd/nand/autcpu12.c | |||
@@ -0,0 +1,225 @@ | |||
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@realitydiluted.com) | ||
8 | * | ||
9 | * $Id: autcpu12.c,v 1.22 2004/11/04 12:53:10 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 | * 16MiB, 32MiB and 64MiB 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 | #include <linux/version.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/mtd/mtd.h> | ||
35 | #include <linux/mtd/nand.h> | ||
36 | #include <linux/mtd/partitions.h> | ||
37 | #include <asm/io.h> | ||
38 | #include <asm/arch/hardware.h> | ||
39 | #include <asm/sizes.h> | ||
40 | #include <asm/arch/autcpu12.h> | ||
41 | |||
42 | /* | ||
43 | * MTD structure for AUTCPU12 board | ||
44 | */ | ||
45 | static struct mtd_info *autcpu12_mtd = NULL; | ||
46 | |||
47 | static int autcpu12_io_base = CS89712_VIRT_BASE; | ||
48 | static int autcpu12_fio_pbase = AUTCPU12_PHYS_SMC; | ||
49 | static int autcpu12_fio_ctrl = AUTCPU12_SMC_SELECT_OFFSET; | ||
50 | static int autcpu12_pedr = AUTCPU12_SMC_PORT_OFFSET; | ||
51 | static void __iomem * autcpu12_fio_base; | ||
52 | |||
53 | /* | ||
54 | * Define partitions for flash devices | ||
55 | */ | ||
56 | static struct mtd_partition partition_info16k[] = { | ||
57 | { .name = "AUTCPU12 flash partition 1", | ||
58 | .offset = 0, | ||
59 | .size = 8 * SZ_1M }, | ||
60 | { .name = "AUTCPU12 flash partition 2", | ||
61 | .offset = 8 * SZ_1M, | ||
62 | .size = 8 * SZ_1M }, | ||
63 | }; | ||
64 | |||
65 | static struct mtd_partition partition_info32k[] = { | ||
66 | { .name = "AUTCPU12 flash partition 1", | ||
67 | .offset = 0, | ||
68 | .size = 8 * SZ_1M }, | ||
69 | { .name = "AUTCPU12 flash partition 2", | ||
70 | .offset = 8 * SZ_1M, | ||
71 | .size = 24 * SZ_1M }, | ||
72 | }; | ||
73 | |||
74 | static struct mtd_partition partition_info64k[] = { | ||
75 | { .name = "AUTCPU12 flash partition 1", | ||
76 | .offset = 0, | ||
77 | .size = 16 * SZ_1M }, | ||
78 | { .name = "AUTCPU12 flash partition 2", | ||
79 | .offset = 16 * SZ_1M, | ||
80 | .size = 48 * SZ_1M }, | ||
81 | }; | ||
82 | |||
83 | static struct mtd_partition partition_info128k[] = { | ||
84 | { .name = "AUTCPU12 flash partition 1", | ||
85 | .offset = 0, | ||
86 | .size = 16 * SZ_1M }, | ||
87 | { .name = "AUTCPU12 flash partition 2", | ||
88 | .offset = 16 * SZ_1M, | ||
89 | .size = 112 * SZ_1M }, | ||
90 | }; | ||
91 | |||
92 | #define NUM_PARTITIONS16K 2 | ||
93 | #define NUM_PARTITIONS32K 2 | ||
94 | #define NUM_PARTITIONS64K 2 | ||
95 | #define NUM_PARTITIONS128K 2 | ||
96 | /* | ||
97 | * hardware specific access to control-lines | ||
98 | */ | ||
99 | static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) | ||
100 | { | ||
101 | |||
102 | switch(cmd){ | ||
103 | |||
104 | case NAND_CTL_SETCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |= AUTCPU12_SMC_CLE; break; | ||
105 | case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_CLE; break; | ||
106 | |||
107 | case NAND_CTL_SETALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |= AUTCPU12_SMC_ALE; break; | ||
108 | case NAND_CTL_CLRALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_ALE; break; | ||
109 | |||
110 | case NAND_CTL_SETNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x01; break; | ||
111 | case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x00; break; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * read device ready pin | ||
117 | */ | ||
118 | int autcpu12_device_ready(struct mtd_info *mtd) | ||
119 | { | ||
120 | |||
121 | return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0; | ||
122 | |||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Main initialization routine | ||
127 | */ | ||
128 | int __init autcpu12_init (void) | ||
129 | { | ||
130 | struct nand_chip *this; | ||
131 | int err = 0; | ||
132 | |||
133 | /* Allocate memory for MTD device structure and private data */ | ||
134 | autcpu12_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), | ||
135 | GFP_KERNEL); | ||
136 | if (!autcpu12_mtd) { | ||
137 | printk ("Unable to allocate AUTCPU12 NAND MTD device structure.\n"); | ||
138 | err = -ENOMEM; | ||
139 | goto out; | ||
140 | } | ||
141 | |||
142 | /* map physical adress */ | ||
143 | autcpu12_fio_base = ioremap(autcpu12_fio_pbase,SZ_1K); | ||
144 | if(!autcpu12_fio_base){ | ||
145 | printk("Ioremap autcpu12 SmartMedia Card failed\n"); | ||
146 | err = -EIO; | ||
147 | goto out_mtd; | ||
148 | } | ||
149 | |||
150 | /* Get pointer to private data */ | ||
151 | this = (struct nand_chip *) (&autcpu12_mtd[1]); | ||
152 | |||
153 | /* Initialize structures */ | ||
154 | memset((char *) autcpu12_mtd, 0, sizeof(struct mtd_info)); | ||
155 | memset((char *) this, 0, sizeof(struct nand_chip)); | ||
156 | |||
157 | /* Link the private data with the MTD structure */ | ||
158 | autcpu12_mtd->priv = this; | ||
159 | |||
160 | /* Set address of NAND IO lines */ | ||
161 | this->IO_ADDR_R = autcpu12_fio_base; | ||
162 | this->IO_ADDR_W = autcpu12_fio_base; | ||
163 | this->hwcontrol = autcpu12_hwcontrol; | ||
164 | this->dev_ready = autcpu12_device_ready; | ||
165 | /* 20 us command delay time */ | ||
166 | this->chip_delay = 20; | ||
167 | this->eccmode = NAND_ECC_SOFT; | ||
168 | |||
169 | /* Enable the following for a flash based bad block table */ | ||
170 | /* | ||
171 | this->options = NAND_USE_FLASH_BBT; | ||
172 | */ | ||
173 | this->options = NAND_USE_FLASH_BBT; | ||
174 | |||
175 | /* Scan to find existance of the device */ | ||
176 | if (nand_scan (autcpu12_mtd, 1)) { | ||
177 | err = -ENXIO; | ||
178 | goto out_ior; | ||
179 | } | ||
180 | |||
181 | /* Register the partitions */ | ||
182 | switch(autcpu12_mtd->size){ | ||
183 | case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; | ||
184 | case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; | ||
185 | case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; | ||
186 | case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; | ||
187 | default: { | ||
188 | printk ("Unsupported SmartMedia device\n"); | ||
189 | err = -ENXIO; | ||
190 | goto out_ior; | ||
191 | } | ||
192 | } | ||
193 | goto out; | ||
194 | |||
195 | out_ior: | ||
196 | iounmap((void *)autcpu12_fio_base); | ||
197 | out_mtd: | ||
198 | kfree (autcpu12_mtd); | ||
199 | out: | ||
200 | return err; | ||
201 | } | ||
202 | |||
203 | module_init(autcpu12_init); | ||
204 | |||
205 | /* | ||
206 | * Clean up routine | ||
207 | */ | ||
208 | #ifdef MODULE | ||
209 | static void __exit autcpu12_cleanup (void) | ||
210 | { | ||
211 | /* Release resources, unregister device */ | ||
212 | nand_release (autcpu12_mtd); | ||
213 | |||
214 | /* unmap physical adress */ | ||
215 | iounmap((void *)autcpu12_fio_base); | ||
216 | |||
217 | /* Free the MTD device structure */ | ||
218 | kfree (autcpu12_mtd); | ||
219 | } | ||
220 | module_exit(autcpu12_cleanup); | ||
221 | #endif | ||
222 | |||
223 | MODULE_LICENSE("GPL"); | ||
224 | MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>"); | ||
225 | MODULE_DESCRIPTION("Glue layer for SmartMediaCard on autronix autcpu12"); | ||