File: /usr/src/linux/drivers/mtd/chips/cfi_jedec.c
1 /* $Id: cfi_jedec.c,v 1.5 2001/06/02 14:52:23 dwmw2 Exp $ */
2
3 #include <linux/config.h>
4 #include <linux/module.h>
5 #include <linux/types.h>
6 #include <linux/kernel.h>
7 #include <asm/io.h>
8 #include <asm/byteorder.h>
9 #include <linux/errno.h>
10 #include <linux/slab.h>
11
12 #include <linux/mtd/map.h>
13 #include <linux/mtd/cfi.h>
14
15 /* Manufacturers */
16 #define MANUFACTURER_AMD 0x0001
17 #define MANUFACTURER_FUJITSU 0x0004
18 #define MANUFACTURER_ATMEL 0x001f
19 #define MANUFACTURER_ST 0x0020
20 #define MANUFACTURER_SST 0x00BF
21 #define MANUFACTURER_TOSHIBA 0x0098
22
23 /* AMD */
24 #define AM29F800BB 0x2258
25 #define AM29F800BT 0x22D6
26 #define AM29LV800BB 0x225B
27 #define AM29LV800BT 0x22DA
28 #define AM29LV160DT 0x22C4
29 #define AM29LV160DB 0x2249
30
31 /* Atmel */
32 #define AT49BV16X4 0x00c0
33 #define AT49BV16X4T 0x00c2
34
35 /* Fujitsu */
36 #define MBM29LV160TE 0x22C4
37 #define MBM29LV160BE 0x2249
38
39 /* ST - www.st.com */
40 #define M29W800T 0x00D7
41 #define M29W160DT 0x22C4
42 #define M29W160DB 0x2249
43
44 /* SST */
45 #define SST39LF800 0x2781
46 #define SST39LF160 0x2782
47
48 /* Toshiba */
49 #define TC58FVT160 0x00C2
50 #define TC58FVB160 0x0043
51
52
53 struct amd_flash_info {
54 const __u16 mfr_id;
55 const __u16 dev_id;
56 const char *name;
57 const int DevSize;
58 const int InterfaceDesc;
59 const int NumEraseRegions;
60 const ulong regions[4];
61 };
62
63 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
64
65 #define SIZE_1MiB 20
66 #define SIZE_2MiB 21
67 #define SIZE_4MiB 22
68
69 static const struct amd_flash_info jedec_table[] = {
70 {
71 mfr_id: MANUFACTURER_AMD,
72 dev_id: AM29LV160DT,
73 name: "AMD AM29LV160DT",
74 DevSize: SIZE_2MiB,
75 NumEraseRegions: 4,
76 regions: {ERASEINFO(0x10000,31),
77 ERASEINFO(0x08000,1),
78 ERASEINFO(0x02000,2),
79 ERASEINFO(0x04000,1)
80 }
81 }, {
82 mfr_id: MANUFACTURER_AMD,
83 dev_id: AM29LV160DB,
84 name: "AMD AM29LV160DB",
85 DevSize: SIZE_2MiB,
86 NumEraseRegions: 4,
87 regions: {ERASEINFO(0x04000,1),
88 ERASEINFO(0x02000,2),
89 ERASEINFO(0x08000,1),
90 ERASEINFO(0x10000,31)
91 }
92 }, {
93 mfr_id: MANUFACTURER_TOSHIBA,
94 dev_id: TC58FVT160,
95 name: "Toshiba TC58FVT160",
96 DevSize: SIZE_2MiB,
97 NumEraseRegions: 4,
98 regions: {ERASEINFO(0x10000,31),
99 ERASEINFO(0x08000,1),
100 ERASEINFO(0x02000,2),
101 ERASEINFO(0x04000,1)
102 }
103 }, {
104 mfr_id: MANUFACTURER_FUJITSU,
105 dev_id: MBM29LV160TE,
106 name: "Fujitsu MBM29LV160TE",
107 DevSize: SIZE_2MiB,
108 NumEraseRegions: 4,
109 regions: {ERASEINFO(0x10000,31),
110 ERASEINFO(0x08000,1),
111 ERASEINFO(0x02000,2),
112 ERASEINFO(0x04000,1)
113 }
114 }, {
115 mfr_id: MANUFACTURER_TOSHIBA,
116 dev_id: TC58FVB160,
117 name: "Toshiba TC58FVB160",
118 DevSize: SIZE_2MiB,
119 NumEraseRegions: 4,
120 regions: {ERASEINFO(0x04000,1),
121 ERASEINFO(0x02000,2),
122 ERASEINFO(0x08000,1),
123 ERASEINFO(0x10000,31)
124 }
125 }, {
126 mfr_id: MANUFACTURER_FUJITSU,
127 dev_id: MBM29LV160BE,
128 name: "Fujitsu MBM29LV160BE",
129 DevSize: SIZE_2MiB,
130 NumEraseRegions: 4,
131 regions: {ERASEINFO(0x04000,1),
132 ERASEINFO(0x02000,2),
133 ERASEINFO(0x08000,1),
134 ERASEINFO(0x10000,31)
135 }
136 }, {
137 mfr_id: MANUFACTURER_AMD,
138 dev_id: AM29LV800BB,
139 name: "AMD AM29LV800BB",
140 DevSize: SIZE_1MiB,
141 NumEraseRegions: 4,
142 regions: {ERASEINFO(0x04000,1),
143 ERASEINFO(0x02000,2),
144 ERASEINFO(0x08000,1),
145 ERASEINFO(0x10000,15),
146 }
147 }, {
148 mfr_id: MANUFACTURER_AMD,
149 dev_id: AM29F800BB,
150 name: "AMD AM29F800BB",
151 DevSize: SIZE_1MiB,
152 NumEraseRegions: 4,
153 regions: {ERASEINFO(0x04000,1),
154 ERASEINFO(0x02000,2),
155 ERASEINFO(0x08000,1),
156 ERASEINFO(0x10000,15),
157 }
158 }, {
159 mfr_id: MANUFACTURER_AMD,
160 dev_id: AM29LV800BT,
161 name: "AMD AM29LV800BT",
162 DevSize: SIZE_1MiB,
163 NumEraseRegions: 4,
164 regions: {ERASEINFO(0x10000,15),
165 ERASEINFO(0x08000,1),
166 ERASEINFO(0x02000,2),
167 ERASEINFO(0x04000,1)
168 }
169 }, {
170 mfr_id: MANUFACTURER_AMD,
171 dev_id: AM29F800BT,
172 name: "AMD AM29F800BT",
173 DevSize: SIZE_1MiB,
174 NumEraseRegions: 4,
175 regions: {ERASEINFO(0x10000,15),
176 ERASEINFO(0x08000,1),
177 ERASEINFO(0x02000,2),
178 ERASEINFO(0x04000,1)
179 }
180 }, {
181 mfr_id: MANUFACTURER_AMD,
182 dev_id: AM29LV800BB,
183 name: "AMD AM29LV800BB",
184 DevSize: SIZE_1MiB,
185 NumEraseRegions: 4,
186 regions: {ERASEINFO(0x10000,15),
187 ERASEINFO(0x08000,1),
188 ERASEINFO(0x02000,2),
189 ERASEINFO(0x04000,1)
190 }
191 }, {
192 mfr_id: MANUFACTURER_ST,
193 dev_id: M29W800T,
194 name: "ST M29W800T",
195 DevSize: SIZE_1MiB,
196 NumEraseRegions: 4,
197 regions: {ERASEINFO(0x10000,15),
198 ERASEINFO(0x08000,1),
199 ERASEINFO(0x02000,2),
200 ERASEINFO(0x04000,1)
201 }
202 }, {
203 mfr_id: MANUFACTURER_ST,
204 dev_id: M29W160DT,
205 name: "ST M29W160DT",
206 DevSize: SIZE_2MiB,
207 NumEraseRegions: 4,
208 regions: {ERASEINFO(0x10000,31),
209 ERASEINFO(0x08000,1),
210 ERASEINFO(0x02000,2),
211 ERASEINFO(0x04000,1)
212 }
213 }, {
214 mfr_id: MANUFACTURER_ST,
215 dev_id: M29W160DB,
216 name: "ST M29W160DB",
217 DevSize: SIZE_2MiB,
218 NumEraseRegions: 4,
219 regions: {ERASEINFO(0x04000,1),
220 ERASEINFO(0x02000,2),
221 ERASEINFO(0x08000,1),
222 ERASEINFO(0x10000,31)
223 }
224 }, {
225 mfr_id: MANUFACTURER_ATMEL,
226 dev_id: AT49BV16X4,
227 name: "Atmel AT49BV16X4",
228 DevSize: SIZE_2MiB,
229 NumEraseRegions: 3,
230 regions: {ERASEINFO(0x02000,8),
231 ERASEINFO(0x08000,2),
232 ERASEINFO(0x10000,30)
233 }
234 }, {
235 mfr_id: MANUFACTURER_ATMEL,
236 dev_id: AT49BV16X4T,
237 name: "Atmel AT49BV16X4T",
238 DevSize: SIZE_2MiB,
239 NumEraseRegions: 3,
240 regions: {ERASEINFO(0x10000,30),
241 ERASEINFO(0x08000,2),
242 ERASEINFO(0x02000,8)
243 }
244 }, {
245 0
246 }
247 };
248
249 int cfi_jedec_lookup(int index, int mfr_id, int dev_id)
250 {
251 if (index>=0){
252 if (jedec_table[index].mfr_id == mfr_id &&
253 jedec_table[index].dev_id == dev_id) return index;
254 }
255 else{
256 for (index=0; jedec_table[index].mfr_id; index++){
257 if (jedec_table[index].mfr_id == mfr_id &&
258 jedec_table[index].dev_id == dev_id) return index;
259 }
260 }
261 return -1;
262 }
263
264 int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
265 {
266 int i,num_erase_regions;
267
268 printk("Found: %s\n",jedec_table[index].name);
269
270 num_erase_regions = jedec_table[index].NumEraseRegions;
271
272 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
273 if (!p_cfi->cfiq) {
274 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
275 return -1;
276 }
277
278 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
279
280 p_cfi->cfiq->P_ID = P_ID_AMD_STD;
281 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
282 p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
283
284 for (i=0; i<num_erase_regions; i++){
285 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
286 }
287 return 0; /* ok */
288 }
289
290