Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / drivers / mtd / chips / jedec_probe.c
1 /* 
2    Common Flash Interface probe code.
3    (C) 2000 Red Hat. GPL'd.
4    $Id: jedec_probe.c,v 1.61 2004/11/19 20:52:16 thayne Exp $
5    See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
6    for the standard this probe goes back to.
7
8    Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
9 */
10
11 #include <linux/config.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <asm/io.h>
17 #include <asm/byteorder.h>
18 #include <linux/errno.h>
19 #include <linux/slab.h>
20 #include <linux/interrupt.h>
21 #include <linux/init.h>
22
23 #include <linux/mtd/mtd.h>
24 #include <linux/mtd/map.h>
25 #include <linux/mtd/cfi.h>
26 #include <linux/mtd/gen_probe.h>
27
28 /* Manufacturers */
29 #define MANUFACTURER_AMD        0x0001
30 #define MANUFACTURER_ATMEL      0x001f
31 #define MANUFACTURER_FUJITSU    0x0004
32 #define MANUFACTURER_HYUNDAI    0x00AD
33 #define MANUFACTURER_INTEL      0x0089
34 #define MANUFACTURER_MACRONIX   0x00C2
35 #define MANUFACTURER_NEC        0x0010
36 #define MANUFACTURER_PMC        0x009D
37 #define MANUFACTURER_SST        0x00BF
38 #define MANUFACTURER_ST         0x0020
39 #define MANUFACTURER_TOSHIBA    0x0098
40 #define MANUFACTURER_WINBOND    0x00da
41
42
43 /* AMD */
44 #define AM29DL800BB     0x22C8
45 #define AM29DL800BT     0x224A
46
47 #define AM29F800BB      0x2258
48 #define AM29F800BT      0x22D6
49 #define AM29LV400BB     0x22BA
50 #define AM29LV400BT     0x22B9
51 #define AM29LV800BB     0x225B
52 #define AM29LV800BT     0x22DA
53 #define AM29LV160DT     0x22C4
54 #define AM29LV160DB     0x2249
55 #define AM29F017D       0x003D
56 #define AM29F016D       0x00AD
57 #define AM29F080        0x00D5
58 #define AM29F040        0x00A4
59 #define AM29LV040B      0x004F
60 #define AM29F032B       0x0041
61 #define AM29F002T       0x00B0
62
63 /* Atmel */
64 #define AT49BV512       0x0003
65 #define AT29LV512       0x003d
66 #define AT49BV16X       0x00C0
67 #define AT49BV16XT      0x00C2
68 #define AT49BV32X       0x00C8
69 #define AT49BV32XT      0x00C9
70
71 /* Fujitsu */
72 #define MBM29F040C      0x00A4
73 #define MBM29LV650UE    0x22D7
74 #define MBM29LV320TE    0x22F6
75 #define MBM29LV320BE    0x22F9
76 #define MBM29LV160TE    0x22C4
77 #define MBM29LV160BE    0x2249
78 #define MBM29LV800BA    0x225B
79 #define MBM29LV800TA    0x22DA
80 #define MBM29LV400TC    0x22B9
81 #define MBM29LV400BC    0x22BA
82
83 /* Hyundai */
84 #define HY29F002T       0x00B0
85
86 /* Intel */
87 #define I28F004B3T      0x00d4
88 #define I28F004B3B      0x00d5
89 #define I28F400B3T      0x8894
90 #define I28F400B3B      0x8895
91 #define I28F008S5       0x00a6
92 #define I28F016S5       0x00a0
93 #define I28F008SA       0x00a2
94 #define I28F008B3T      0x00d2
95 #define I28F008B3B      0x00d3
96 #define I28F800B3T      0x8892
97 #define I28F800B3B      0x8893
98 #define I28F016S3       0x00aa
99 #define I28F016B3T      0x00d0
100 #define I28F016B3B      0x00d1
101 #define I28F160B3T      0x8890
102 #define I28F160B3B      0x8891
103 #define I28F320B3T      0x8896
104 #define I28F320B3B      0x8897
105 #define I28F640B3T      0x8898
106 #define I28F640B3B      0x8899
107 #define I82802AB        0x00ad
108 #define I82802AC        0x00ac
109
110 /* Macronix */
111 #define MX29LV040C      0x004F
112 #define MX29LV160T      0x22C4
113 #define MX29LV160B      0x2249
114 #define MX29F016        0x00AD
115 #define MX29F002T       0x00B0
116 #define MX29F004T       0x0045
117 #define MX29F004B       0x0046
118
119 /* NEC */
120 #define UPD29F064115    0x221C
121
122 /* PMC */
123 #define PM49FL002       0x006D
124 #define PM49FL004       0x006E
125 #define PM49FL008       0x006A
126
127 /* ST - www.st.com */
128 #define M29W800DT       0x00D7
129 #define M29W800DB       0x005B
130 #define M29W160DT       0x22C4
131 #define M29W160DB       0x2249
132 #define M29W040B        0x00E3
133 #define M50FW040        0x002C
134 #define M50FW080        0x002D
135 #define M50FW016        0x002E
136 #define M50LPW080       0x002F
137
138 /* SST */
139 #define SST29EE020      0x0010
140 #define SST29LE020      0x0012
141 #define SST29EE512      0x005d
142 #define SST29LE512      0x003d
143 #define SST39LF800      0x2781
144 #define SST39LF160      0x2782
145 #define SST39LF512      0x00D4
146 #define SST39LF010      0x00D5
147 #define SST39LF020      0x00D6
148 #define SST39LF040      0x00D7
149 #define SST39SF010A     0x00B5
150 #define SST39SF020A     0x00B6
151 #define SST49LF004B     0x0060
152 #define SST49LF008A     0x005a
153 #define SST49LF030A     0x001C
154 #define SST49LF040A     0x0051
155 #define SST49LF080A     0x005B
156
157 /* Toshiba */
158 #define TC58FVT160      0x00C2
159 #define TC58FVB160      0x0043
160 #define TC58FVT321      0x009A
161 #define TC58FVB321      0x009C
162 #define TC58FVT641      0x0093
163 #define TC58FVB641      0x0095
164
165 /* Winbond */
166 #define W49V002A        0x00b0
167
168
169 /*
170  * Unlock address sets for AMD command sets.
171  * Intel command sets use the MTD_UADDR_UNNECESSARY.
172  * Each identifier, except MTD_UADDR_UNNECESSARY, and
173  * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[].
174  * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure
175  * initialization need not require initializing all of the
176  * unlock addresses for all bit widths.
177  */
178 enum uaddr {
179         MTD_UADDR_NOT_SUPPORTED = 0,    /* data width not supported */
180         MTD_UADDR_0x0555_0x02AA,
181         MTD_UADDR_0x0555_0x0AAA,
182         MTD_UADDR_0x5555_0x2AAA,
183         MTD_UADDR_0x0AAA_0x0555,
184         MTD_UADDR_DONT_CARE,            /* Requires an arbitrary address */
185         MTD_UADDR_UNNECESSARY,          /* Does not require any address */
186 };
187
188
189 struct unlock_addr {
190         u32 addr1;
191         u32 addr2;
192 };
193
194
195 /*
196  * I don't like the fact that the first entry in unlock_addrs[]
197  * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
198  * should not be used.  The  problem is that structures with
199  * initializers have extra fields initialized to 0.  It is _very_
200  * desireable to have the unlock address entries for unsupported
201  * data widths automatically initialized - that means that
202  * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
203  * must go unused.
204  */
205 static const struct unlock_addr  unlock_addrs[] = {
206         [MTD_UADDR_NOT_SUPPORTED] = {
207                 .addr1 = 0xffff,
208                 .addr2 = 0xffff
209         },
210
211         [MTD_UADDR_0x0555_0x02AA] = {
212                 .addr1 = 0x0555,
213                 .addr2 = 0x02aa
214         },
215
216         [MTD_UADDR_0x0555_0x0AAA] = {
217                 .addr1 = 0x0555,
218                 .addr2 = 0x0aaa
219         },
220
221         [MTD_UADDR_0x5555_0x2AAA] = {
222                 .addr1 = 0x5555,
223                 .addr2 = 0x2aaa
224         },
225
226         [MTD_UADDR_0x0AAA_0x0555] = {
227                 .addr1 = 0x0AAA,
228                 .addr2 = 0x0555
229         },
230
231         [MTD_UADDR_DONT_CARE] = {
232                 .addr1 = 0x0000,      /* Doesn't matter which address */
233                 .addr2 = 0x0000       /* is used - must be last entry */
234         },
235
236         [MTD_UADDR_UNNECESSARY] = {
237                 .addr1 = 0x0000,
238                 .addr2 = 0x0000
239         }
240 };
241
242
243 struct amd_flash_info {
244         const __u16 mfr_id;
245         const __u16 dev_id;
246         const char *name;
247         const int DevSize;
248         const int NumEraseRegions;
249         const int CmdSet;
250         const __u8 uaddr[4];            /* unlock addrs for 8, 16, 32, 64 */
251         const ulong regions[6];
252 };
253
254 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
255
256 #define SIZE_64KiB  16
257 #define SIZE_128KiB 17
258 #define SIZE_256KiB 18
259 #define SIZE_512KiB 19
260 #define SIZE_1MiB   20
261 #define SIZE_2MiB   21
262 #define SIZE_4MiB   22
263 #define SIZE_8MiB   23
264
265
266 /*
267  * Please keep this list ordered by manufacturer!
268  * Fortunately, the list isn't searched often and so a
269  * slow, linear search isn't so bad.
270  */
271 static const struct amd_flash_info jedec_table[] = {
272         {
273                 .mfr_id         = MANUFACTURER_AMD,
274                 .dev_id         = AM29F032B,
275                 .name           = "AMD AM29F032B",
276                 .uaddr          = {
277                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
278                 },
279                 .DevSize        = SIZE_4MiB,
280                 .CmdSet         = P_ID_AMD_STD,
281                 .NumEraseRegions= 1,
282                 .regions        = {
283                         ERASEINFO(0x10000,64)
284                 }
285         }, {
286                 .mfr_id         = MANUFACTURER_AMD,
287                 .dev_id         = AM29LV160DT,
288                 .name           = "AMD AM29LV160DT",
289                 .uaddr          = {
290                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
291                         [1] = MTD_UADDR_0x0555_0x02AA   /* x16 */
292                 },
293                 .DevSize        = SIZE_2MiB,
294                 .CmdSet         = P_ID_AMD_STD,
295                 .NumEraseRegions= 4,
296                 .regions        = {
297                         ERASEINFO(0x10000,31),
298                         ERASEINFO(0x08000,1),
299                         ERASEINFO(0x02000,2),
300                         ERASEINFO(0x04000,1)
301                 }
302         }, {
303                 .mfr_id         = MANUFACTURER_AMD,
304                 .dev_id         = AM29LV160DB,
305                 .name           = "AMD AM29LV160DB",
306                 .uaddr          = {
307                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
308                         [1] = MTD_UADDR_0x0555_0x02AA   /* x16 */
309                 },
310                 .DevSize        = SIZE_2MiB,
311                 .CmdSet         = P_ID_AMD_STD,
312                 .NumEraseRegions= 4,
313                 .regions        = {
314                         ERASEINFO(0x04000,1),
315                         ERASEINFO(0x02000,2),
316                         ERASEINFO(0x08000,1),
317                         ERASEINFO(0x10000,31)
318                 }
319         }, {
320                 .mfr_id         = MANUFACTURER_AMD,
321                 .dev_id         = AM29LV400BB,
322                 .name           = "AMD AM29LV400BB",
323                 .uaddr          = {
324                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
325                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
326                 },
327                 .DevSize        = SIZE_512KiB,
328                 .CmdSet         = P_ID_AMD_STD,
329                 .NumEraseRegions= 4,
330                 .regions        = {
331                         ERASEINFO(0x04000,1),
332                         ERASEINFO(0x02000,2),
333                         ERASEINFO(0x08000,1),
334                         ERASEINFO(0x10000,7)
335                 }
336         }, {
337                 .mfr_id         = MANUFACTURER_AMD,
338                 .dev_id         = AM29LV400BT,
339                 .name           = "AMD AM29LV400BT",
340                 .uaddr          = {
341                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
342                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
343                 },
344                 .DevSize        = SIZE_512KiB,
345                 .CmdSet         = P_ID_AMD_STD,
346                 .NumEraseRegions= 4,
347                 .regions        = {
348                         ERASEINFO(0x10000,7),
349                         ERASEINFO(0x08000,1),
350                         ERASEINFO(0x02000,2),
351                         ERASEINFO(0x04000,1)
352                 }
353         }, {
354                 .mfr_id         = MANUFACTURER_AMD,
355                 .dev_id         = AM29LV800BB,
356                 .name           = "AMD AM29LV800BB",
357                 .uaddr          = {
358                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
359                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
360                 },
361                 .DevSize        = SIZE_1MiB,
362                 .CmdSet         = P_ID_AMD_STD,
363                 .NumEraseRegions= 4,
364                 .regions        = {
365                         ERASEINFO(0x04000,1),
366                         ERASEINFO(0x02000,2),
367                         ERASEINFO(0x08000,1),
368                         ERASEINFO(0x10000,15),
369                 }
370         }, {
371 /* add DL */
372                 .mfr_id         = MANUFACTURER_AMD,
373                 .dev_id         = AM29DL800BB,
374                 .name           = "AMD AM29DL800BB",
375                 .uaddr          = {
376                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
377                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
378                 },
379                 .DevSize        = SIZE_1MiB,
380                 .CmdSet         = P_ID_AMD_STD,
381                 .NumEraseRegions= 6,
382                 .regions        = {
383                         ERASEINFO(0x04000,1),
384                         ERASEINFO(0x08000,1),
385                         ERASEINFO(0x02000,4),
386                         ERASEINFO(0x08000,1),
387                         ERASEINFO(0x04000,1),
388                         ERASEINFO(0x10000,14)
389                 }
390         }, {
391                 .mfr_id         = MANUFACTURER_AMD,
392                 .dev_id         = AM29DL800BT,
393                 .name           = "AMD AM29DL800BT",
394                 .uaddr          = {
395                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
396                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
397                 },
398                 .DevSize        = SIZE_1MiB,
399                 .CmdSet         = P_ID_AMD_STD,
400                 .NumEraseRegions= 6,
401                 .regions        = {
402                         ERASEINFO(0x10000,14),
403                         ERASEINFO(0x04000,1),
404                         ERASEINFO(0x08000,1),
405                         ERASEINFO(0x02000,4),
406                         ERASEINFO(0x08000,1),
407                         ERASEINFO(0x04000,1)
408                 }
409         }, {
410                 .mfr_id         = MANUFACTURER_AMD,
411                 .dev_id         = AM29F800BB,
412                 .name           = "AMD AM29F800BB",
413                 .uaddr          = {
414                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
415                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
416                 },
417                 .DevSize        = SIZE_1MiB,
418                 .CmdSet         = P_ID_AMD_STD,
419                 .NumEraseRegions= 4,
420                 .regions        = {
421                         ERASEINFO(0x04000,1),
422                         ERASEINFO(0x02000,2),
423                         ERASEINFO(0x08000,1),
424                         ERASEINFO(0x10000,15),
425                 }
426         }, {
427                 .mfr_id         = MANUFACTURER_AMD,
428                 .dev_id         = AM29LV800BT,
429                 .name           = "AMD AM29LV800BT",
430                 .uaddr          = {
431                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
432                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
433                 },
434                 .DevSize        = SIZE_1MiB,
435                 .CmdSet         = P_ID_AMD_STD,
436                 .NumEraseRegions= 4,
437                 .regions        = {
438                         ERASEINFO(0x10000,15),
439                         ERASEINFO(0x08000,1),
440                         ERASEINFO(0x02000,2),
441                         ERASEINFO(0x04000,1)
442                 }
443         }, {
444                 .mfr_id         = MANUFACTURER_AMD,
445                 .dev_id         = AM29F800BT,
446                 .name           = "AMD AM29F800BT",
447                 .uaddr          = {
448                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
449                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
450                 },
451                 .DevSize        = SIZE_1MiB,
452                 .CmdSet         = P_ID_AMD_STD,
453                 .NumEraseRegions= 4,
454                 .regions        = {
455                         ERASEINFO(0x10000,15),
456                         ERASEINFO(0x08000,1),
457                         ERASEINFO(0x02000,2),
458                         ERASEINFO(0x04000,1)
459                 }
460         }, {
461                 .mfr_id         = MANUFACTURER_AMD,
462                 .dev_id         = AM29F017D,
463                 .name           = "AMD AM29F017D",
464                 .uaddr          = {
465                         [0] = MTD_UADDR_DONT_CARE     /* x8 */
466                 },
467                 .DevSize        = SIZE_2MiB,
468                 .CmdSet         = P_ID_AMD_STD,
469                 .NumEraseRegions= 1,
470                 .regions        = {
471                         ERASEINFO(0x10000,32),
472                 }
473         }, {
474                 .mfr_id         = MANUFACTURER_AMD,
475                 .dev_id         = AM29F016D,
476                 .name           = "AMD AM29F016D",
477                 .uaddr          = {
478                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
479                 },
480                 .DevSize        = SIZE_2MiB,
481                 .CmdSet         = P_ID_AMD_STD,
482                 .NumEraseRegions= 1,
483                 .regions        = {
484                         ERASEINFO(0x10000,32),
485                 }
486         }, {
487                 .mfr_id         = MANUFACTURER_AMD,
488                 .dev_id         = AM29F080,
489                 .name           = "AMD AM29F080",
490                 .uaddr          = {
491                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
492                 },
493                 .DevSize        = SIZE_1MiB,
494                 .CmdSet         = P_ID_AMD_STD,
495                 .NumEraseRegions= 1,
496                 .regions        = {
497                         ERASEINFO(0x10000,16),
498                 }
499         }, {
500                 .mfr_id         = MANUFACTURER_AMD,
501                 .dev_id         = AM29F040,
502                 .name           = "AMD AM29F040",
503                 .uaddr          = {
504                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
505                 },
506                 .DevSize        = SIZE_512KiB,
507                 .CmdSet         = P_ID_AMD_STD,
508                 .NumEraseRegions= 1,
509                 .regions        = {
510                         ERASEINFO(0x10000,8),
511                 }
512         }, {
513                 .mfr_id         = MANUFACTURER_AMD,
514                 .dev_id         = AM29LV040B,
515                 .name           = "AMD AM29LV040B",
516                 .uaddr          = {
517                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
518                 },
519                 .DevSize        = SIZE_512KiB,
520                 .CmdSet         = P_ID_AMD_STD,
521                 .NumEraseRegions= 1,
522                 .regions        = {
523                         ERASEINFO(0x10000,8),
524                 }
525         }, {
526                 .mfr_id         = MANUFACTURER_AMD,
527                 .dev_id         = AM29F002T,
528                 .name           = "AMD AM29F002T",
529                 .uaddr          = {
530                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
531                 },
532                 .DevSize        = SIZE_256KiB,
533                 .CmdSet         = P_ID_AMD_STD,
534                 .NumEraseRegions= 4,
535                 .regions        = {
536                         ERASEINFO(0x10000,3),
537                         ERASEINFO(0x08000,1),
538                         ERASEINFO(0x02000,2),
539                         ERASEINFO(0x04000,1),
540                 }
541         }, {
542                 .mfr_id         = MANUFACTURER_ATMEL,
543                 .dev_id         = AT49BV512,
544                 .name           = "Atmel AT49BV512",
545                 .uaddr          = {
546                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
547                 },
548                 .DevSize        = SIZE_64KiB,
549                 .CmdSet         = P_ID_AMD_STD,
550                 .NumEraseRegions= 1,
551                 .regions        = {
552                         ERASEINFO(0x10000,1)
553                 }
554         }, {
555                 .mfr_id         = MANUFACTURER_ATMEL,
556                 .dev_id         = AT29LV512,
557                 .name           = "Atmel AT29LV512",
558                 .uaddr          = {
559                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
560                 },
561                 .DevSize        = SIZE_64KiB,
562                 .CmdSet         = P_ID_AMD_STD,
563                 .NumEraseRegions= 1,
564                 .regions        = {
565                         ERASEINFO(0x80,256),
566                         ERASEINFO(0x80,256)
567                 }
568         }, {
569                 .mfr_id         = MANUFACTURER_ATMEL,
570                 .dev_id         = AT49BV16X,
571                 .name           = "Atmel AT49BV16X",
572                 .uaddr          = {
573                         [0] = MTD_UADDR_0x0555_0x0AAA,  /* x8 */
574                         [1] = MTD_UADDR_0x0555_0x0AAA   /* x16 */
575                 },
576                 .DevSize        = SIZE_2MiB,
577                 .CmdSet         = P_ID_AMD_STD,
578                 .NumEraseRegions= 2,
579                 .regions        = {
580                         ERASEINFO(0x02000,8),
581                         ERASEINFO(0x10000,31)
582                 }
583         }, {
584                 .mfr_id         = MANUFACTURER_ATMEL,
585                 .dev_id         = AT49BV16XT,
586                 .name           = "Atmel AT49BV16XT",
587                 .uaddr          = {
588                         [0] = MTD_UADDR_0x0555_0x0AAA,  /* x8 */
589                         [1] = MTD_UADDR_0x0555_0x0AAA   /* x16 */
590                 },
591                 .DevSize        = SIZE_2MiB,
592                 .CmdSet         = P_ID_AMD_STD,
593                 .NumEraseRegions= 2,
594                 .regions        = {
595                         ERASEINFO(0x10000,31),
596                         ERASEINFO(0x02000,8)
597                 }
598         }, {
599                 .mfr_id         = MANUFACTURER_ATMEL,
600                 .dev_id         = AT49BV32X,
601                 .name           = "Atmel AT49BV32X",
602                 .uaddr          = {
603                         [0] = MTD_UADDR_0x0555_0x0AAA,  /* x8 */
604                         [1] = MTD_UADDR_0x0555_0x0AAA   /* x16 */
605                 },
606                 .DevSize        = SIZE_4MiB,
607                 .CmdSet         = P_ID_AMD_STD,
608                 .NumEraseRegions= 2,
609                 .regions        = {
610                         ERASEINFO(0x02000,8),
611                         ERASEINFO(0x10000,63)
612                 }
613         }, {
614                 .mfr_id         = MANUFACTURER_ATMEL,
615                 .dev_id         = AT49BV32XT,
616                 .name           = "Atmel AT49BV32XT",
617                 .uaddr          = {
618                         [0] = MTD_UADDR_0x0555_0x0AAA,  /* x8 */
619                         [1] = MTD_UADDR_0x0555_0x0AAA   /* x16 */
620                 },
621                 .DevSize        = SIZE_4MiB,
622                 .CmdSet         = P_ID_AMD_STD,
623                 .NumEraseRegions= 2,
624                 .regions        = {
625                         ERASEINFO(0x10000,63),
626                         ERASEINFO(0x02000,8)
627                 }
628         }, {
629                 .mfr_id         = MANUFACTURER_FUJITSU,
630                 .dev_id         = MBM29F040C,
631                 .name           = "Fujitsu MBM29F040C",
632                 .uaddr          = {
633                         [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
634                 },
635                 .DevSize        = SIZE_512KiB,
636                 .CmdSet         = P_ID_AMD_STD,
637                 .NumEraseRegions= 1,
638                 .regions        = {
639                         ERASEINFO(0x10000,8)
640                 }
641         }, {
642                 .mfr_id         = MANUFACTURER_FUJITSU,
643                 .dev_id         = MBM29LV650UE,
644                 .name           = "Fujitsu MBM29LV650UE",
645                 .uaddr          = {
646                         [0] = MTD_UADDR_DONT_CARE     /* x16 */
647                 },
648                 .DevSize        = SIZE_8MiB,
649                 .CmdSet         = P_ID_AMD_STD,
650                 .NumEraseRegions= 1,
651                 .regions        = {
652                         ERASEINFO(0x10000,128)
653                 }
654         }, {
655                 .mfr_id         = MANUFACTURER_FUJITSU,
656                 .dev_id         = MBM29LV320TE,
657                 .name           = "Fujitsu MBM29LV320TE",
658                 .uaddr          = {
659                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
660                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
661                 },
662                 .DevSize        = SIZE_4MiB,
663                 .CmdSet         = P_ID_AMD_STD,
664                 .NumEraseRegions= 2,
665                 .regions        = {
666                         ERASEINFO(0x10000,63),
667                         ERASEINFO(0x02000,8)
668                 }
669         }, {
670                 .mfr_id         = MANUFACTURER_FUJITSU,
671                 .dev_id         = MBM29LV320BE,
672                 .name           = "Fujitsu MBM29LV320BE",
673                 .uaddr          = {
674                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
675                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
676                 },
677                 .DevSize        = SIZE_4MiB,
678                 .CmdSet         = P_ID_AMD_STD,
679                 .NumEraseRegions= 2,
680                 .regions        = {
681                         ERASEINFO(0x02000,8),
682                         ERASEINFO(0x10000,63)
683                 }
684         }, {
685                 .mfr_id         = MANUFACTURER_FUJITSU,
686                 .dev_id         = MBM29LV160TE,
687                 .name           = "Fujitsu MBM29LV160TE",
688                 .uaddr          = {
689                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
690                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
691                 },
692                 .DevSize        = SIZE_2MiB,
693                 .CmdSet         = P_ID_AMD_STD,
694                 .NumEraseRegions= 4,
695                 .regions        = {
696                         ERASEINFO(0x10000,31),
697                         ERASEINFO(0x08000,1),
698                         ERASEINFO(0x02000,2),
699                         ERASEINFO(0x04000,1)
700                 }
701         }, {
702                 .mfr_id         = MANUFACTURER_FUJITSU,
703                 .dev_id         = MBM29LV160BE,
704                 .name           = "Fujitsu MBM29LV160BE",
705                 .uaddr          = {
706                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
707                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
708                 },
709                 .DevSize        = SIZE_2MiB,
710                 .CmdSet         = P_ID_AMD_STD,
711                 .NumEraseRegions= 4,
712                 .regions        = {
713                         ERASEINFO(0x04000,1),
714                         ERASEINFO(0x02000,2),
715                         ERASEINFO(0x08000,1),
716                         ERASEINFO(0x10000,31)
717                 }
718         }, {
719                 .mfr_id         = MANUFACTURER_FUJITSU,
720                 .dev_id         = MBM29LV800BA,
721                 .name           = "Fujitsu MBM29LV800BA",
722                 .uaddr          = {
723                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
724                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
725                 },
726                 .DevSize        = SIZE_1MiB,
727                 .CmdSet         = P_ID_AMD_STD,
728                 .NumEraseRegions= 4,
729                 .regions        = {
730                         ERASEINFO(0x04000,1),
731                         ERASEINFO(0x02000,2),
732                         ERASEINFO(0x08000,1),
733                         ERASEINFO(0x10000,15)
734                 }
735         }, {
736                 .mfr_id         = MANUFACTURER_FUJITSU,
737                 .dev_id         = MBM29LV800TA,
738                 .name           = "Fujitsu MBM29LV800TA",
739                 .uaddr          = {
740                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
741                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
742                 },
743                 .DevSize        = SIZE_1MiB,
744                 .CmdSet         = P_ID_AMD_STD,
745                 .NumEraseRegions= 4,
746                 .regions        = {
747                         ERASEINFO(0x10000,15),
748                         ERASEINFO(0x08000,1),
749                         ERASEINFO(0x02000,2),
750                         ERASEINFO(0x04000,1)
751                 }
752         }, {
753                 .mfr_id         = MANUFACTURER_FUJITSU,
754                 .dev_id         = MBM29LV400BC,
755                 .name           = "Fujitsu MBM29LV400BC",
756                 .uaddr          = {
757                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
758                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
759                 },
760                 .DevSize        = SIZE_512KiB,
761                 .CmdSet         = P_ID_AMD_STD,
762                 .NumEraseRegions= 4,
763                 .regions        = {
764                         ERASEINFO(0x04000,1),
765                         ERASEINFO(0x02000,2),
766                         ERASEINFO(0x08000,1),
767                         ERASEINFO(0x10000,7)
768                 }
769         }, {
770                 .mfr_id         = MANUFACTURER_FUJITSU,
771                 .dev_id         = MBM29LV400TC,
772                 .name           = "Fujitsu MBM29LV400TC",
773                 .uaddr          = {
774                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
775                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
776                 },
777                 .DevSize        = SIZE_512KiB,
778                 .CmdSet         = P_ID_AMD_STD,
779                 .NumEraseRegions= 4,
780                 .regions        = {
781                         ERASEINFO(0x10000,7),
782                         ERASEINFO(0x08000,1),
783                         ERASEINFO(0x02000,2),
784                         ERASEINFO(0x04000,1)
785                 }
786         }, {
787                 .mfr_id         = MANUFACTURER_HYUNDAI,
788                 .dev_id         = HY29F002T,
789                 .name           = "Hyundai HY29F002T",
790                 .uaddr          = {
791                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
792                 },
793                 .DevSize        = SIZE_256KiB,
794                 .CmdSet         = P_ID_AMD_STD,
795                 .NumEraseRegions= 4,
796                 .regions        = {
797                         ERASEINFO(0x10000,3),
798                         ERASEINFO(0x08000,1),
799                         ERASEINFO(0x02000,2),
800                         ERASEINFO(0x04000,1),
801                 }
802         }, {
803                 .mfr_id         = MANUFACTURER_INTEL,
804                 .dev_id         = I28F004B3B,
805                 .name           = "Intel 28F004B3B",
806                 .uaddr          = {
807                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
808                 },
809                 .DevSize        = SIZE_512KiB,
810                 .CmdSet         = P_ID_INTEL_STD,
811                 .NumEraseRegions= 2,
812                 .regions        = {
813                         ERASEINFO(0x02000, 8),
814                         ERASEINFO(0x10000, 7),
815                 }
816         }, {
817                 .mfr_id         = MANUFACTURER_INTEL,
818                 .dev_id         = I28F004B3T,
819                 .name           = "Intel 28F004B3T",
820                 .uaddr          = {
821                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
822                 },
823                 .DevSize        = SIZE_512KiB,
824                 .CmdSet         = P_ID_INTEL_STD,
825                 .NumEraseRegions= 2,
826                 .regions        = {
827                         ERASEINFO(0x10000, 7),
828                         ERASEINFO(0x02000, 8),
829                 }
830         }, {
831                 .mfr_id         = MANUFACTURER_INTEL,
832                 .dev_id         = I28F400B3B,
833                 .name           = "Intel 28F400B3B",
834                 .uaddr          = {
835                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
836                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
837                 },
838                 .DevSize        = SIZE_512KiB,
839                 .CmdSet         = P_ID_INTEL_STD,
840                 .NumEraseRegions= 2,
841                 .regions        = {
842                         ERASEINFO(0x02000, 8),
843                         ERASEINFO(0x10000, 7),
844                 }
845         }, {
846                 .mfr_id         = MANUFACTURER_INTEL,
847                 .dev_id         = I28F400B3T,
848                 .name           = "Intel 28F400B3T",
849                 .uaddr          = {
850                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
851                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
852                 },
853                 .DevSize        = SIZE_512KiB,
854                 .CmdSet         = P_ID_INTEL_STD,
855                 .NumEraseRegions= 2,
856                 .regions        = {
857                         ERASEINFO(0x10000, 7),
858                         ERASEINFO(0x02000, 8),
859                 }
860         }, {
861                 .mfr_id         = MANUFACTURER_INTEL,
862                 .dev_id         = I28F008B3B,
863                 .name           = "Intel 28F008B3B",
864                 .uaddr          = {
865                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
866                 },
867                 .DevSize        = SIZE_1MiB,
868                 .CmdSet         = P_ID_INTEL_STD,
869                 .NumEraseRegions= 2,
870                 .regions        = {
871                         ERASEINFO(0x02000, 8),
872                         ERASEINFO(0x10000, 15),
873                 }
874         }, {
875                 .mfr_id         = MANUFACTURER_INTEL,
876                 .dev_id         = I28F008B3T,
877                 .name           = "Intel 28F008B3T",
878                 .uaddr          = {
879                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
880                 },
881                 .DevSize        = SIZE_1MiB,
882                 .CmdSet         = P_ID_INTEL_STD,
883                 .NumEraseRegions= 2,
884                 .regions        = {
885                         ERASEINFO(0x10000, 15),
886                         ERASEINFO(0x02000, 8),
887                 }
888         }, {
889                 .mfr_id         = MANUFACTURER_INTEL,
890                 .dev_id         = I28F008S5,
891                 .name           = "Intel 28F008S5",
892                 .uaddr          = {
893                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
894                 },
895                 .DevSize        = SIZE_1MiB,
896                 .CmdSet         = P_ID_INTEL_EXT,
897                 .NumEraseRegions= 1,
898                 .regions        = {
899                         ERASEINFO(0x10000,16),
900                 }
901         }, {
902                 .mfr_id         = MANUFACTURER_INTEL,
903                 .dev_id         = I28F016S5,
904                 .name           = "Intel 28F016S5",
905                 .uaddr          = {
906                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
907                 },
908                 .DevSize        = SIZE_2MiB,
909                 .CmdSet         = P_ID_INTEL_EXT,
910                 .NumEraseRegions= 1,
911                 .regions        = {
912                         ERASEINFO(0x10000,32),
913                 }
914         }, {
915                 .mfr_id         = MANUFACTURER_INTEL,
916                 .dev_id         = I28F008SA,
917                 .name           = "Intel 28F008SA",
918                 .uaddr          = {
919                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
920                 },
921                 .DevSize        = SIZE_1MiB,
922                 .CmdSet         = P_ID_INTEL_STD,
923                 .NumEraseRegions= 1,
924                 .regions        = {
925                         ERASEINFO(0x10000, 16),
926                 }
927         }, {
928                 .mfr_id         = MANUFACTURER_INTEL,
929                 .dev_id         = I28F800B3B,
930                 .name           = "Intel 28F800B3B",
931                 .uaddr          = {
932                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
933                 },
934                 .DevSize        = SIZE_1MiB,
935                 .CmdSet         = P_ID_INTEL_STD,
936                 .NumEraseRegions= 2,
937                 .regions        = {
938                         ERASEINFO(0x02000, 8),
939                         ERASEINFO(0x10000, 15),
940                 }
941         }, {
942                 .mfr_id         = MANUFACTURER_INTEL,
943                 .dev_id         = I28F800B3T,
944                 .name           = "Intel 28F800B3T",
945                 .uaddr          = {
946                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
947                 },
948                 .DevSize        = SIZE_1MiB,
949                 .CmdSet         = P_ID_INTEL_STD,
950                 .NumEraseRegions= 2,
951                 .regions        = {
952                         ERASEINFO(0x10000, 15),
953                         ERASEINFO(0x02000, 8),
954                 }
955         }, {
956                 .mfr_id         = MANUFACTURER_INTEL,
957                 .dev_id         = I28F016B3B,
958                 .name           = "Intel 28F016B3B",
959                 .uaddr          = {
960                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
961                 },
962                 .DevSize        = SIZE_2MiB,
963                 .CmdSet         = P_ID_INTEL_STD,
964                 .NumEraseRegions= 2,
965                 .regions        = {
966                         ERASEINFO(0x02000, 8),
967                         ERASEINFO(0x10000, 31),
968                 }
969         }, {
970                 .mfr_id         = MANUFACTURER_INTEL,
971                 .dev_id         = I28F016S3,
972                 .name           = "Intel I28F016S3",
973                 .uaddr          = {
974                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
975                 },
976                 .DevSize        = SIZE_2MiB,
977                 .CmdSet         = P_ID_INTEL_STD,
978                 .NumEraseRegions= 1,
979                 .regions        = {
980                         ERASEINFO(0x10000, 32),
981                 }
982         }, {
983                 .mfr_id         = MANUFACTURER_INTEL,
984                 .dev_id         = I28F016B3T,
985                 .name           = "Intel 28F016B3T",
986                 .uaddr          = {
987                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
988                 },
989                 .DevSize        = SIZE_2MiB,
990                 .CmdSet         = P_ID_INTEL_STD,
991                 .NumEraseRegions= 2,
992                 .regions        = {
993                         ERASEINFO(0x10000, 31),
994                         ERASEINFO(0x02000, 8),
995                 }
996         }, {
997                 .mfr_id         = MANUFACTURER_INTEL,
998                 .dev_id         = I28F160B3B,
999                 .name           = "Intel 28F160B3B",
1000                 .uaddr          = {
1001                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
1002                 },
1003                 .DevSize        = SIZE_2MiB,
1004                 .CmdSet         = P_ID_INTEL_STD,
1005                 .NumEraseRegions= 2,
1006                 .regions        = {
1007                         ERASEINFO(0x02000, 8),
1008                         ERASEINFO(0x10000, 31),
1009                 }
1010         }, {
1011                 .mfr_id         = MANUFACTURER_INTEL,
1012                 .dev_id         = I28F160B3T,
1013                 .name           = "Intel 28F160B3T",
1014                 .uaddr          = {
1015                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
1016                 },
1017                 .DevSize        = SIZE_2MiB,
1018                 .CmdSet         = P_ID_INTEL_STD,
1019                 .NumEraseRegions= 2,
1020                 .regions        = {
1021                         ERASEINFO(0x10000, 31),
1022                         ERASEINFO(0x02000, 8),
1023                 }
1024         }, {
1025                 .mfr_id         = MANUFACTURER_INTEL,
1026                 .dev_id         = I28F320B3B,
1027                 .name           = "Intel 28F320B3B",
1028                 .uaddr          = {
1029                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
1030                 },
1031                 .DevSize        = SIZE_4MiB,
1032                 .CmdSet         = P_ID_INTEL_STD,
1033                 .NumEraseRegions= 2,
1034                 .regions        = {
1035                         ERASEINFO(0x02000, 8),
1036                         ERASEINFO(0x10000, 63),
1037                 }
1038         }, {
1039                 .mfr_id         = MANUFACTURER_INTEL,
1040                 .dev_id         = I28F320B3T,
1041                 .name           = "Intel 28F320B3T",
1042                 .uaddr          = {
1043                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
1044                 },
1045                 .DevSize        = SIZE_4MiB,
1046                 .CmdSet         = P_ID_INTEL_STD,
1047                 .NumEraseRegions= 2,
1048                 .regions        = {
1049                         ERASEINFO(0x10000, 63),
1050                         ERASEINFO(0x02000, 8),
1051                 }
1052         }, {
1053                 .mfr_id         = MANUFACTURER_INTEL,
1054                 .dev_id         = I28F640B3B,
1055                 .name           = "Intel 28F640B3B",
1056                 .uaddr          = {
1057                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
1058                 },
1059                 .DevSize        = SIZE_8MiB,
1060                 .CmdSet         = P_ID_INTEL_STD,
1061                 .NumEraseRegions= 2,
1062                 .regions        = {
1063                         ERASEINFO(0x02000, 8),
1064                         ERASEINFO(0x10000, 127),
1065                 }
1066         }, {
1067                 .mfr_id         = MANUFACTURER_INTEL,
1068                 .dev_id         = I28F640B3T,
1069                 .name           = "Intel 28F640B3T",
1070                 .uaddr          = {
1071                         [1] = MTD_UADDR_UNNECESSARY,    /* x16 */
1072                 },
1073                 .DevSize        = SIZE_8MiB,
1074                 .CmdSet         = P_ID_INTEL_STD,
1075                 .NumEraseRegions= 2,
1076                 .regions        = {
1077                         ERASEINFO(0x10000, 127),
1078                         ERASEINFO(0x02000, 8),
1079                 }
1080         }, {
1081                 .mfr_id         = MANUFACTURER_INTEL,
1082                 .dev_id         = I82802AB,
1083                 .name           = "Intel 82802AB",
1084                 .uaddr          = {
1085                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
1086                 },
1087                 .DevSize        = SIZE_512KiB,
1088                 .CmdSet         = P_ID_INTEL_EXT,
1089                 .NumEraseRegions= 1,
1090                 .regions        = {
1091                         ERASEINFO(0x10000,8),
1092                 }
1093         }, {
1094                 .mfr_id         = MANUFACTURER_INTEL,
1095                 .dev_id         = I82802AC,
1096                 .name           = "Intel 82802AC",
1097                 .uaddr          = {
1098                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
1099                 },
1100                 .DevSize        = SIZE_1MiB,
1101                 .CmdSet         = P_ID_INTEL_EXT,
1102                 .NumEraseRegions= 1,
1103                 .regions        = {
1104                         ERASEINFO(0x10000,16),
1105                 }
1106         }, {
1107                 .mfr_id         = MANUFACTURER_MACRONIX,
1108                 .dev_id         = MX29LV040C,
1109                 .name           = "Macronix MX29LV040C",
1110                 .uaddr          = {
1111                         [0] = MTD_UADDR_0x0555_0x02AA,  /* x8 */
1112                 },
1113                 .DevSize        = SIZE_512KiB,
1114                 .CmdSet         = P_ID_AMD_STD,
1115                 .NumEraseRegions= 1,
1116                 .regions        = {
1117                         ERASEINFO(0x10000,8),
1118                 }
1119         }, {
1120                 .mfr_id         = MANUFACTURER_MACRONIX,
1121                 .dev_id         = MX29LV160T,
1122                 .name           = "MXIC MX29LV160T",
1123                 .uaddr          = {
1124                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
1125                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
1126                 },
1127                 .DevSize        = SIZE_2MiB,
1128                 .CmdSet         = P_ID_AMD_STD,
1129                 .NumEraseRegions= 4,
1130                 .regions        = {
1131                         ERASEINFO(0x10000,31),
1132                         ERASEINFO(0x08000,1),
1133                         ERASEINFO(0x02000,2),
1134                         ERASEINFO(0x04000,1)
1135                 }
1136         }, {
1137                 .mfr_id         = MANUFACTURER_NEC,
1138                 .dev_id         = UPD29F064115,
1139                 .name           = "NEC uPD29F064115",
1140                 .uaddr          = {
1141                         [0] = MTD_UADDR_0x0555_0x02AA,  /* x8 */
1142                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
1143                 },
1144                 .DevSize        = SIZE_8MiB,
1145                 .CmdSet         = P_ID_AMD_STD,
1146                 .NumEraseRegions= 3,
1147                 .regions        = {
1148                         ERASEINFO(0x2000,8),
1149                         ERASEINFO(0x10000,126),
1150                         ERASEINFO(0x2000,8),
1151                 }
1152         }, {
1153                 .mfr_id         = MANUFACTURER_MACRONIX,
1154                 .dev_id         = MX29LV160B,
1155                 .name           = "MXIC MX29LV160B",
1156                 .uaddr          = {
1157                         [0] = MTD_UADDR_0x0AAA_0x0555,  /* x8 */
1158                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
1159                 },
1160                 .DevSize        = SIZE_2MiB,
1161                 .CmdSet         = P_ID_AMD_STD,
1162                 .NumEraseRegions= 4,
1163                 .regions        = {
1164                         ERASEINFO(0x04000,1),
1165                         ERASEINFO(0x02000,2),
1166                         ERASEINFO(0x08000,1),
1167                         ERASEINFO(0x10000,31)
1168                 }
1169         }, {
1170                 .mfr_id         = MANUFACTURER_MACRONIX,
1171                 .dev_id         = MX29F016,
1172                 .name           = "Macronix MX29F016",
1173                 .uaddr          = {
1174                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1175                 },
1176                 .DevSize        = SIZE_2MiB,
1177                 .CmdSet         = P_ID_AMD_STD,
1178                 .NumEraseRegions= 1,
1179                 .regions        = {
1180                         ERASEINFO(0x10000,32),
1181                 }
1182         }, {
1183                 .mfr_id         = MANUFACTURER_MACRONIX,
1184                 .dev_id         = MX29F004T,
1185                 .name           = "Macronix MX29F004T",
1186                 .uaddr          = {
1187                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1188                 },
1189                 .DevSize        = SIZE_512KiB,
1190                 .CmdSet         = P_ID_AMD_STD,
1191                 .NumEraseRegions= 4,
1192                 .regions        = {
1193                         ERASEINFO(0x10000,7),
1194                         ERASEINFO(0x08000,1),
1195                         ERASEINFO(0x02000,2),
1196                         ERASEINFO(0x04000,1),
1197                 }
1198         }, {
1199                 .mfr_id         = MANUFACTURER_MACRONIX,
1200                 .dev_id         = MX29F004B,
1201                 .name           = "Macronix MX29F004B",
1202                 .uaddr          = {
1203                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1204                 },
1205                 .DevSize        = SIZE_512KiB,
1206                 .CmdSet         = P_ID_AMD_STD,
1207                 .NumEraseRegions= 4,
1208                 .regions        = {
1209                         ERASEINFO(0x04000,1),
1210                         ERASEINFO(0x02000,2),
1211                         ERASEINFO(0x08000,1),
1212                         ERASEINFO(0x10000,7),
1213                 }
1214         }, {
1215                 .mfr_id         = MANUFACTURER_MACRONIX,
1216                 .dev_id         = MX29F002T,
1217                 .name           = "Macronix MX29F002T",
1218                 .uaddr          = {
1219                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1220                 },
1221                 .DevSize        = SIZE_256KiB,
1222                 .CmdSet         = P_ID_AMD_STD,
1223                 .NumEraseRegions= 4,
1224                 .regions        = {
1225                         ERASEINFO(0x10000,3),
1226                         ERASEINFO(0x08000,1),
1227                         ERASEINFO(0x02000,2),
1228                         ERASEINFO(0x04000,1),
1229                 }
1230         }, {
1231                 .mfr_id         = MANUFACTURER_PMC,
1232                 .dev_id         = PM49FL002,
1233                 .name           = "PMC Pm49FL002",
1234                 .uaddr          = {
1235                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1236                 },
1237                 .DevSize        = SIZE_256KiB,
1238                 .CmdSet         = P_ID_AMD_STD,
1239                 .NumEraseRegions= 1,
1240                 .regions        = {
1241                         ERASEINFO( 0x01000, 64 )
1242                 }
1243         }, {
1244                 .mfr_id         = MANUFACTURER_PMC,
1245                 .dev_id         = PM49FL004,
1246                 .name           = "PMC Pm49FL004",
1247                 .uaddr          = {
1248                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1249                 },
1250                 .DevSize        = SIZE_512KiB,
1251                 .CmdSet         = P_ID_AMD_STD,
1252                 .NumEraseRegions= 1,
1253                 .regions        = {
1254                         ERASEINFO( 0x01000, 128 )
1255                 }
1256         }, {
1257                 .mfr_id         = MANUFACTURER_PMC,
1258                 .dev_id         = PM49FL008,
1259                 .name           = "PMC Pm49FL008",
1260                 .uaddr          = {
1261                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1262                 },
1263                 .DevSize        = SIZE_1MiB,
1264                 .CmdSet         = P_ID_AMD_STD,
1265                 .NumEraseRegions= 1,
1266                 .regions        = {
1267                         ERASEINFO( 0x01000, 256 )
1268                 }
1269         }, {
1270                 .mfr_id         = MANUFACTURER_SST,
1271                 .dev_id         = SST39LF512,
1272                 .name           = "SST 39LF512",
1273                 .uaddr          = {
1274                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1275                 },
1276                 .DevSize        = SIZE_64KiB,
1277                 .CmdSet         = P_ID_AMD_STD,
1278                 .NumEraseRegions= 1,
1279                 .regions        = {
1280                         ERASEINFO(0x01000,16),
1281                 }
1282         }, {
1283                 .mfr_id         = MANUFACTURER_SST,
1284                 .dev_id         = SST39LF010,
1285                 .name           = "SST 39LF010",
1286                 .uaddr          = {
1287                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1288                 },
1289                 .DevSize        = SIZE_128KiB,
1290                 .CmdSet         = P_ID_AMD_STD,
1291                 .NumEraseRegions= 1,
1292                 .regions        = {
1293                         ERASEINFO(0x01000,32),
1294                 }
1295         }, {
1296                 .mfr_id         = MANUFACTURER_SST,
1297                 .dev_id         = SST29EE020,
1298                 .name           = "SST 29EE020",
1299                 .uaddr          = {
1300                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1301                 },
1302                 .DevSize        = SIZE_256KiB,
1303                 .CmdSet         = P_ID_SST_PAGE,
1304                 .NumEraseRegions= 1,
1305                 .regions = {ERASEINFO(0x01000,64),
1306                 }
1307          }, {
1308                 .mfr_id         = MANUFACTURER_SST,
1309                 .dev_id         = SST29LE020,
1310                 .name           = "SST 29LE020",
1311                 .uaddr          = {
1312                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1313                 },
1314                 .DevSize        = SIZE_256KiB,
1315                 .CmdSet         = P_ID_SST_PAGE,
1316                 .NumEraseRegions= 1,
1317                 .regions = {ERASEINFO(0x01000,64),
1318                 }
1319         }, {
1320                 .mfr_id         = MANUFACTURER_SST,
1321                 .dev_id         = SST39LF020,
1322                 .name           = "SST 39LF020",
1323                 .uaddr          = {
1324                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1325                 },
1326                 .DevSize        = SIZE_256KiB,
1327                 .CmdSet         = P_ID_AMD_STD,
1328                 .NumEraseRegions= 1,
1329                 .regions        = {
1330                         ERASEINFO(0x01000,64),
1331                 }
1332         }, {
1333                 .mfr_id         = MANUFACTURER_SST,
1334                 .dev_id         = SST39LF040,
1335                 .name           = "SST 39LF040",
1336                 .uaddr          = {
1337                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1338                 },
1339                 .DevSize        = SIZE_512KiB,
1340                 .CmdSet         = P_ID_AMD_STD,
1341                 .NumEraseRegions= 1,
1342                 .regions        = {
1343                         ERASEINFO(0x01000,128),
1344                 }
1345         }, {
1346                 .mfr_id         = MANUFACTURER_SST,
1347                 .dev_id         = SST39SF010A,
1348                 .name           = "SST 39SF010A",
1349                 .uaddr          = {
1350                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1351                 },
1352                 .DevSize        = SIZE_128KiB,
1353                 .CmdSet         = P_ID_AMD_STD,
1354                 .NumEraseRegions= 1,
1355                 .regions        = {
1356                         ERASEINFO(0x01000,32),
1357                 }
1358         }, {
1359                 .mfr_id         = MANUFACTURER_SST,
1360                 .dev_id         = SST39SF020A,
1361                 .name           = "SST 39SF020A",
1362                 .uaddr          = {
1363                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1364                 },
1365                 .DevSize        = SIZE_256KiB,
1366                 .CmdSet         = P_ID_AMD_STD,
1367                 .NumEraseRegions= 1,
1368                 .regions        = {
1369                         ERASEINFO(0x01000,64),
1370                 }
1371         }, {
1372                 .mfr_id         = MANUFACTURER_SST,
1373                 .dev_id         = SST49LF004B,
1374                 .name           = "SST 49LF004B",
1375                 .uaddr          = {
1376                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1377                 },
1378                 .DevSize        = SIZE_512KiB,
1379                 .CmdSet         = P_ID_AMD_STD,
1380                 .NumEraseRegions= 1,
1381                 .regions        = {
1382                         ERASEINFO(0x01000,128),
1383                 }
1384         }, {
1385                 .mfr_id         = MANUFACTURER_SST,
1386                 .dev_id         = SST49LF008A,
1387                 .name           = "SST 49LF008A",
1388                 .uaddr          = {
1389                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1390                 },
1391                 .DevSize        = SIZE_1MiB,
1392                 .CmdSet         = P_ID_AMD_STD,
1393                 .NumEraseRegions= 1,
1394                 .regions        = {
1395                         ERASEINFO(0x01000,256),
1396                 }
1397         }, {
1398                 .mfr_id         = MANUFACTURER_SST,
1399                 .dev_id         = SST49LF030A,
1400                 .name           = "SST 49LF030A",
1401                 .uaddr          = {
1402                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1403                 },
1404                 .DevSize        = SIZE_512KiB,
1405                 .CmdSet         = P_ID_AMD_STD,
1406                 .NumEraseRegions= 1,
1407                 .regions        = {
1408                         ERASEINFO(0x01000,96),
1409                 }
1410         }, {
1411                 .mfr_id         = MANUFACTURER_SST,
1412                 .dev_id         = SST49LF040A,
1413                 .name           = "SST 49LF040A",
1414                 .uaddr          = {
1415                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1416                 },
1417                 .DevSize        = SIZE_512KiB,
1418                 .CmdSet         = P_ID_AMD_STD,
1419                 .NumEraseRegions= 1,
1420                 .regions        = {
1421                         ERASEINFO(0x01000,128),
1422                 }
1423         }, {
1424                 .mfr_id         = MANUFACTURER_SST,
1425                 .dev_id         = SST49LF080A,
1426                 .name           = "SST 49LF080A",
1427                 .uaddr          = {
1428                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1429                 },
1430                 .DevSize        = SIZE_1MiB,
1431                 .CmdSet         = P_ID_AMD_STD,
1432                 .NumEraseRegions= 1,
1433                 .regions        = {
1434                         ERASEINFO(0x01000,256),
1435                 }
1436         }, {
1437                .mfr_id         = MANUFACTURER_SST,     /* should be CFI */
1438                .dev_id         = SST39LF160,
1439                .name           = "SST 39LF160",
1440                .uaddr          = {
1441                        [0] = MTD_UADDR_0x5555_0x2AAA,  /* x8 */
1442                        [1] = MTD_UADDR_0x5555_0x2AAA   /* x16 */
1443                },
1444                .DevSize        = SIZE_2MiB,
1445                .CmdSet         = P_ID_AMD_STD,
1446                .NumEraseRegions= 2,
1447                .regions        = {
1448                        ERASEINFO(0x1000,256),
1449                        ERASEINFO(0x1000,256)
1450                }
1451
1452        }, {
1453                 .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
1454                 .dev_id         = M29W800DT,
1455                 .name           = "ST M29W800DT",
1456                 .uaddr          = {
1457                         [0] = MTD_UADDR_0x5555_0x2AAA,  /* x8 */
1458                         [1] = MTD_UADDR_0x5555_0x2AAA   /* x16 */
1459                 },
1460                 .DevSize        = SIZE_1MiB,
1461                 .CmdSet         = P_ID_AMD_STD,
1462                 .NumEraseRegions= 4,
1463                 .regions        = {
1464                         ERASEINFO(0x10000,15),
1465                         ERASEINFO(0x08000,1),
1466                         ERASEINFO(0x02000,2),
1467                         ERASEINFO(0x04000,1)
1468                 }
1469         }, {
1470                 .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
1471                 .dev_id         = M29W800DB,
1472                 .name           = "ST M29W800DB",
1473                 .uaddr          = {
1474                         [0] = MTD_UADDR_0x5555_0x2AAA,  /* x8 */
1475                         [1] = MTD_UADDR_0x5555_0x2AAA   /* x16 */
1476                 },
1477                 .DevSize        = SIZE_1MiB,
1478                 .CmdSet         = P_ID_AMD_STD,
1479                 .NumEraseRegions= 4,
1480                 .regions        = {
1481                         ERASEINFO(0x04000,1),
1482                         ERASEINFO(0x02000,2),
1483                         ERASEINFO(0x08000,1),
1484                         ERASEINFO(0x10000,15)
1485                 }
1486         }, {
1487                 .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
1488                 .dev_id         = M29W160DT,
1489                 .name           = "ST M29W160DT",
1490                 .uaddr          = {
1491                         [0] = MTD_UADDR_0x0555_0x02AA,  /* x8 */
1492                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
1493                 },
1494                 .DevSize        = SIZE_2MiB,
1495                 .CmdSet         = P_ID_AMD_STD,
1496                 .NumEraseRegions= 4,
1497                 .regions        = {
1498                         ERASEINFO(0x10000,31),
1499                         ERASEINFO(0x08000,1),
1500                         ERASEINFO(0x02000,2),
1501                         ERASEINFO(0x04000,1)
1502                 }
1503         }, {
1504                 .mfr_id         = MANUFACTURER_ST,      /* FIXME - CFI device? */
1505                 .dev_id         = M29W160DB,
1506                 .name           = "ST M29W160DB",
1507                 .uaddr          = {
1508                         [0] = MTD_UADDR_0x0555_0x02AA,  /* x8 */
1509                         [1] = MTD_UADDR_0x0555_0x02AA,  /* x16 */
1510                 },
1511                 .DevSize        = SIZE_2MiB,
1512                 .CmdSet         = P_ID_AMD_STD,
1513                 .NumEraseRegions= 4,
1514                 .regions        = {
1515                         ERASEINFO(0x04000,1),
1516                         ERASEINFO(0x02000,2),
1517                         ERASEINFO(0x08000,1),
1518                         ERASEINFO(0x10000,31)
1519                 }
1520         }, {
1521                 .mfr_id         = MANUFACTURER_ST,
1522                 .dev_id         = M29W040B,
1523                 .name           = "ST M29W040B",
1524                 .uaddr          = {
1525                         [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1526                 },
1527                 .DevSize        = SIZE_512KiB,
1528                 .CmdSet         = P_ID_AMD_STD,
1529                 .NumEraseRegions= 1,
1530                 .regions        = {
1531                         ERASEINFO(0x10000,8),
1532                 }
1533         }, {
1534                 .mfr_id         = MANUFACTURER_ST,
1535                 .dev_id         = M50FW040,
1536                 .name           = "ST M50FW040",
1537                 .uaddr          = {
1538                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
1539                 },
1540                 .DevSize        = SIZE_512KiB,
1541                 .CmdSet         = P_ID_INTEL_EXT,
1542                 .NumEraseRegions= 1,
1543                 .regions        = {
1544                         ERASEINFO(0x10000,8),
1545                 }
1546         }, {
1547                 .mfr_id         = MANUFACTURER_ST,
1548                 .dev_id         = M50FW080,
1549                 .name           = "ST M50FW080",
1550                 .uaddr          = {
1551                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
1552                 },
1553                 .DevSize        = SIZE_1MiB,
1554                 .CmdSet         = P_ID_INTEL_EXT,
1555                 .NumEraseRegions= 1,
1556                 .regions        = {
1557                         ERASEINFO(0x10000,16),
1558                 }
1559         }, {
1560                 .mfr_id         = MANUFACTURER_ST,
1561                 .dev_id         = M50FW016,
1562                 .name           = "ST M50FW016",
1563                 .uaddr          = {
1564                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
1565                 },
1566                 .DevSize        = SIZE_2MiB,
1567                 .CmdSet         = P_ID_INTEL_EXT,
1568                 .NumEraseRegions= 1,
1569                 .regions        = {
1570                         ERASEINFO(0x10000,32),
1571                 }
1572         }, {
1573                 .mfr_id         = MANUFACTURER_ST,
1574                 .dev_id         = M50LPW080,
1575                 .name           = "ST M50LPW080",
1576                 .uaddr          = {
1577                         [0] = MTD_UADDR_UNNECESSARY,    /* x8 */
1578                 },
1579                 .DevSize        = SIZE_1MiB,
1580                 .CmdSet         = P_ID_INTEL_EXT,
1581                 .NumEraseRegions= 1,
1582                 .regions        = {
1583                         ERASEINFO(0x10000,16),
1584                 }
1585         }, {
1586                 .mfr_id         = MANUFACTURER_TOSHIBA,
1587                 .dev_id         = TC58FVT160,
1588                 .name           = "Toshiba TC58FVT160",
1589                 .uaddr          = {
1590                         [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1591                         [1] = MTD_UADDR_0x0555_0x02AA  /* x16 */
1592                 },
1593                 .DevSize        = SIZE_2MiB,
1594                 .CmdSet         = P_ID_AMD_STD,
1595                 .NumEraseRegions= 4,
1596                 .regions        = {
1597                         ERASEINFO(0x10000,31),
1598                         ERASEINFO(0x08000,1),
1599                         ERASEINFO(0x02000,2),
1600                         ERASEINFO(0x04000,1)
1601                 }
1602         }, {
1603                 .mfr_id         = MANUFACTURER_TOSHIBA,
1604                 .dev_id         = TC58FVB160,
1605                 .name           = "Toshiba TC58FVB160",
1606                 .uaddr          = {
1607                         [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1608                         [1] = MTD_UADDR_0x0555_0x02AA  /* x16 */
1609                 },
1610                 .DevSize        = SIZE_2MiB,
1611                 .CmdSet         = P_ID_AMD_STD,
1612                 .NumEraseRegions= 4,
1613                 .regions        = {
1614                         ERASEINFO(0x04000,1),
1615                         ERASEINFO(0x02000,2),
1616                         ERASEINFO(0x08000,1),
1617                         ERASEINFO(0x10000,31)
1618                 }
1619         }, {
1620                 .mfr_id         = MANUFACTURER_TOSHIBA,
1621                 .dev_id         = TC58FVB321,
1622                 .name           = "Toshiba TC58FVB321",
1623                 .uaddr          = {
1624                         [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1625                         [1] = MTD_UADDR_0x0555_0x02AA  /* x16 */
1626                 },
1627                 .DevSize        = SIZE_4MiB,
1628                 .CmdSet         = P_ID_AMD_STD,
1629                 .NumEraseRegions= 2,
1630                 .regions        = {
1631                         ERASEINFO(0x02000,8),
1632                         ERASEINFO(0x10000,63)
1633                 }
1634         }, {
1635                 .mfr_id         = MANUFACTURER_TOSHIBA,
1636                 .dev_id         = TC58FVT321,
1637                 .name           = "Toshiba TC58FVT321",
1638                 .uaddr          = {
1639                         [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1640                         [1] = MTD_UADDR_0x0555_0x02AA  /* x16 */
1641                 },
1642                 .DevSize        = SIZE_4MiB,
1643                 .CmdSet         = P_ID_AMD_STD,
1644                 .NumEraseRegions= 2,
1645                 .regions        = {
1646                         ERASEINFO(0x10000,63),
1647                         ERASEINFO(0x02000,8)
1648                 }
1649         }, {
1650                 .mfr_id         = MANUFACTURER_TOSHIBA,
1651                 .dev_id         = TC58FVB641,
1652                 .name           = "Toshiba TC58FVB641",
1653                 .uaddr          = {
1654                         [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1655                         [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1656                 },
1657                 .DevSize        = SIZE_8MiB,
1658                 .CmdSet         = P_ID_AMD_STD,
1659                 .NumEraseRegions= 2,
1660                 .regions        = {
1661                         ERASEINFO(0x02000,8),
1662                         ERASEINFO(0x10000,127)
1663                 }
1664         }, {
1665                 .mfr_id         = MANUFACTURER_TOSHIBA,
1666                 .dev_id         = TC58FVT641,
1667                 .name           = "Toshiba TC58FVT641",
1668                 .uaddr          = {
1669                         [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1670                         [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1671                 },
1672                 .DevSize        = SIZE_8MiB,
1673                 .CmdSet         = P_ID_AMD_STD,
1674                 .NumEraseRegions= 2,
1675                 .regions        = {
1676                         ERASEINFO(0x10000,127),
1677                         ERASEINFO(0x02000,8)
1678                 }
1679         }, {
1680                 .mfr_id         = MANUFACTURER_WINBOND,
1681                 .dev_id         = W49V002A,
1682                 .name           = "Winbond W49V002A",
1683                 .uaddr          = {
1684                         [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1685                 },
1686                 .DevSize        = SIZE_256KiB,
1687                 .CmdSet         = P_ID_AMD_STD,
1688                 .NumEraseRegions= 4,
1689                 .regions        = {
1690                         ERASEINFO(0x10000, 3),
1691                         ERASEINFO(0x08000, 1),
1692                         ERASEINFO(0x02000, 2),
1693                         ERASEINFO(0x04000, 1),
1694                 }
1695         }
1696 };
1697
1698
1699 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
1700
1701 static int jedec_probe_chip(struct map_info *map, __u32 base,
1702                             unsigned long *chip_map, struct cfi_private *cfi);
1703
1704 static struct mtd_info *jedec_probe(struct map_info *map);
1705
1706 static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, 
1707         struct cfi_private *cfi)
1708 {
1709         map_word result;
1710         unsigned long mask;
1711         u32 ofs = cfi_build_cmd_addr(0, cfi_interleave(cfi), cfi->device_type);
1712         mask = (1 << (cfi->device_type * 8)) -1;
1713         result = map_read(map, base + ofs);
1714         return result.x[0] & mask;
1715 }
1716
1717 static inline u32 jedec_read_id(struct map_info *map, __u32 base, 
1718         struct cfi_private *cfi)
1719 {
1720         map_word result;
1721         unsigned long mask;
1722         u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type);
1723         mask = (1 << (cfi->device_type * 8)) -1;
1724         result = map_read(map, base + ofs);
1725         return result.x[0] & mask;
1726 }
1727
1728 static inline void jedec_reset(u32 base, struct map_info *map, 
1729         struct cfi_private *cfi)
1730 {
1731         /* Reset */
1732
1733         /* after checking the datasheets for SST, MACRONIX and ATMEL
1734          * (oh and incidentaly the jedec spec - 3.5.3.3) the reset
1735          * sequence is *supposed* to be 0xaa at 0x5555, 0x55 at
1736          * 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips
1737          * as they will ignore the writes and dont care what address
1738          * the F0 is written to */
1739         if(cfi->addr_unlock1) {
1740                 DEBUG( MTD_DEBUG_LEVEL3,
1741                        "reset unlock called %x %x \n",
1742                        cfi->addr_unlock1,cfi->addr_unlock2);
1743                 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1744                 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
1745         }
1746
1747         cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1748         /* Some misdesigned intel chips do not respond for 0xF0 for a reset,
1749          * so ensure we're in read mode.  Send both the Intel and the AMD command
1750          * for this.  Intel uses 0xff for this, AMD uses 0xff for NOP, so
1751          * this should be safe.
1752          */ 
1753         cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
1754         /* FIXME - should have reset delay before continuing */
1755 }
1756
1757
1758 static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type)
1759 {
1760         int uaddr_idx;
1761         __u8 uaddr = MTD_UADDR_NOT_SUPPORTED;
1762
1763         switch ( device_type ) {
1764         case CFI_DEVICETYPE_X8:  uaddr_idx = 0; break;
1765         case CFI_DEVICETYPE_X16: uaddr_idx = 1; break;
1766         case CFI_DEVICETYPE_X32: uaddr_idx = 2; break;
1767         default:
1768                 printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n",
1769                        __func__, device_type);
1770                 goto uaddr_done;
1771         }
1772
1773         uaddr = finfo->uaddr[uaddr_idx];
1774
1775         if (uaddr != MTD_UADDR_NOT_SUPPORTED ) {
1776                 /* ASSERT("The unlock addresses for non-8-bit mode
1777                    are bollocks. We don't really need an array."); */
1778                 uaddr = finfo->uaddr[0];
1779         }
1780
1781  uaddr_done:
1782         return uaddr;
1783 }
1784
1785
1786 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1787 {
1788         int i,num_erase_regions;
1789         __u8 uaddr;
1790
1791         printk("Found: %s\n",jedec_table[index].name);
1792
1793         num_erase_regions = jedec_table[index].NumEraseRegions;
1794         
1795         p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
1796         if (!p_cfi->cfiq) {
1797                 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
1798                 return 0;
1799         }
1800
1801         memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); 
1802
1803         p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
1804         p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
1805         p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
1806         p_cfi->cfi_mode = CFI_MODE_JEDEC;
1807
1808         for (i=0; i<num_erase_regions; i++){
1809                 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
1810         }
1811         p_cfi->cmdset_priv = NULL;
1812
1813         /* This may be redundant for some cases, but it doesn't hurt */
1814         p_cfi->mfr = jedec_table[index].mfr_id;
1815         p_cfi->id = jedec_table[index].dev_id;
1816
1817         uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type);
1818         if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
1819                 kfree( p_cfi->cfiq );
1820                 return 0;
1821         }
1822
1823         p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1;
1824         p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2;
1825
1826         return 1;       /* ok */
1827 }
1828
1829
1830 /*
1831  * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing
1832  * the mapped address, unlock addresses, and proper chip ID.  This function
1833  * attempts to minimize errors.  It is doubtfull that this probe will ever
1834  * be perfect - consequently there should be some module parameters that
1835  * could be manually specified to force the chip info.
1836  */
1837 static inline int jedec_match( __u32 base,
1838                                struct map_info *map,
1839                                struct cfi_private *cfi,
1840                                const struct amd_flash_info *finfo )
1841 {
1842         int rc = 0;           /* failure until all tests pass */
1843         u32 mfr, id;
1844         __u8 uaddr;
1845
1846         /*
1847          * The IDs must match.  For X16 and X32 devices operating in
1848          * a lower width ( X8 or X16 ), the device ID's are usually just
1849          * the lower byte(s) of the larger device ID for wider mode.  If
1850          * a part is found that doesn't fit this assumption (device id for
1851          * smaller width mode is completely unrealated to full-width mode)
1852          * then the jedec_table[] will have to be augmented with the IDs
1853          * for different widths.
1854          */
1855         switch (cfi->device_type) {
1856         case CFI_DEVICETYPE_X8:
1857                 mfr = (__u8)finfo->mfr_id;
1858                 id = (__u8)finfo->dev_id;
1859                 break;
1860         case CFI_DEVICETYPE_X16:
1861                 mfr = (__u16)finfo->mfr_id;
1862                 id = (__u16)finfo->dev_id;
1863                 break;
1864         case CFI_DEVICETYPE_X32:
1865                 mfr = (__u16)finfo->mfr_id;
1866                 id = (__u32)finfo->dev_id;
1867                 break;
1868         default:
1869                 printk(KERN_WARNING
1870                        "MTD %s(): Unsupported device type %d\n",
1871                        __func__, cfi->device_type);
1872                 goto match_done;
1873         }
1874         if ( cfi->mfr != mfr || cfi->id != id ) {
1875                 goto match_done;
1876         }
1877
1878         /* the part size must fit in the memory window */
1879         DEBUG( MTD_DEBUG_LEVEL3,
1880                "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
1881                __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
1882         if ( base + cfi_interleave(cfi) * ( 1 << finfo->DevSize ) > map->size ) {
1883                 DEBUG( MTD_DEBUG_LEVEL3,
1884                        "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
1885                        __func__, finfo->mfr_id, finfo->dev_id,
1886                        1 << finfo->DevSize );
1887                 goto match_done;
1888         }
1889
1890         uaddr = finfo_uaddr(finfo, cfi->device_type);
1891         if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
1892                 goto match_done;
1893         }
1894
1895         DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
1896                __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
1897         if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
1898              && ( unlock_addrs[uaddr].addr1 != cfi->addr_unlock1 ||
1899                   unlock_addrs[uaddr].addr2 != cfi->addr_unlock2 ) ) {
1900                 DEBUG( MTD_DEBUG_LEVEL3,
1901                         "MTD %s(): 0x%.4x 0x%.4x did not match\n",
1902                         __func__,
1903                         unlock_addrs[uaddr].addr1,
1904                         unlock_addrs[uaddr].addr2);
1905                 goto match_done;
1906         }
1907
1908         /*
1909          * Make sure the ID's dissappear when the device is taken out of
1910          * ID mode.  The only time this should fail when it should succeed
1911          * is when the ID's are written as data to the same
1912          * addresses.  For this rare and unfortunate case the chip
1913          * cannot be probed correctly.
1914          * FIXME - write a driver that takes all of the chip info as
1915          * module parameters, doesn't probe but forces a load.
1916          */
1917         DEBUG( MTD_DEBUG_LEVEL3,
1918                "MTD %s(): check ID's disappear when not in ID mode\n",
1919                __func__ );
1920         jedec_reset( base, map, cfi );
1921         mfr = jedec_read_mfr( map, base, cfi );
1922         id = jedec_read_id( map, base, cfi );
1923         if ( mfr == cfi->mfr && id == cfi->id ) {
1924                 DEBUG( MTD_DEBUG_LEVEL3,
1925                        "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
1926                        "You might need to manually specify JEDEC parameters.\n",
1927                         __func__, cfi->mfr, cfi->id );
1928                 goto match_done;
1929         }
1930
1931         /* all tests passed - mark  as success */
1932         rc = 1;
1933
1934         /*
1935          * Put the device back in ID mode - only need to do this if we
1936          * were truly frobbing a real device.
1937          */
1938         DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
1939         if(cfi->addr_unlock1) {
1940                 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1941                 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
1942         }
1943         cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1944         /* FIXME - should have a delay before continuing */
1945
1946  match_done:    
1947         return rc;
1948 }
1949
1950
1951 static int jedec_probe_chip(struct map_info *map, __u32 base,
1952                             unsigned long *chip_map, struct cfi_private *cfi)
1953 {
1954         int i;
1955         enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED;
1956         u32 probe_offset1, probe_offset2;
1957
1958  retry:
1959         if (!cfi->numchips) {
1960                 uaddr_idx++;
1961
1962                 if (MTD_UADDR_UNNECESSARY == uaddr_idx)
1963                         return 0;
1964
1965                 cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1;
1966                 cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2;
1967         }
1968
1969         /* Make certain we aren't probing past the end of map */
1970         if (base >= map->size) {
1971                 printk(KERN_NOTICE
1972                         "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
1973                         base, map->size -1);
1974                 return 0;
1975                 
1976         }
1977         /* Ensure the unlock addresses we try stay inside the map */
1978         probe_offset1 = cfi_build_cmd_addr(
1979                 cfi->addr_unlock1, 
1980                 cfi_interleave(cfi), 
1981                 cfi->device_type);
1982         probe_offset2 = cfi_build_cmd_addr(
1983                 cfi->addr_unlock1, 
1984                 cfi_interleave(cfi), 
1985                 cfi->device_type);
1986         if (    ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
1987                 ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
1988         {
1989                 goto retry;
1990         }
1991                 
1992         /* Reset */
1993         jedec_reset(base, map, cfi);
1994
1995         /* Autoselect Mode */
1996         if(cfi->addr_unlock1) {
1997                 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1998                 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);
1999         }
2000         cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
2001         /* FIXME - should have a delay before continuing */
2002
2003         if (!cfi->numchips) {
2004                 /* This is the first time we're called. Set up the CFI 
2005                    stuff accordingly and return */
2006                 
2007                 cfi->mfr = jedec_read_mfr(map, base, cfi);
2008                 cfi->id = jedec_read_id(map, base, cfi);
2009                 DEBUG(MTD_DEBUG_LEVEL3,
2010                       "Search for id:(%02x %02x) interleave(%d) type(%d)\n", 
2011                         cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
2012                 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
2013                         if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
2014                                 DEBUG( MTD_DEBUG_LEVEL3,
2015                                        "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
2016                                        __func__, cfi->mfr, cfi->id,
2017                                        cfi->addr_unlock1, cfi->addr_unlock2 );
2018                                 if (!cfi_jedec_setup(cfi, i))
2019                                         return 0;
2020                                 goto ok_out;
2021                         }
2022                 }
2023                 goto retry;
2024         } else {
2025                 __u16 mfr;
2026                 __u16 id;
2027
2028                 /* Make sure it is a chip of the same manufacturer and id */
2029                 mfr = jedec_read_mfr(map, base, cfi);
2030                 id = jedec_read_id(map, base, cfi);
2031
2032                 if ((mfr != cfi->mfr) || (id != cfi->id)) {
2033                         printk(KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n",
2034                                map->name, mfr, id, base);
2035                         jedec_reset(base, map, cfi);
2036                         return 0;
2037                 }
2038         }
2039         
2040         /* Check each previous chip locations to see if it's an alias */
2041         for (i=0; i < (base >> cfi->chipshift); i++) {
2042                 unsigned long start;
2043                 if(!test_bit(i, chip_map)) {
2044                         continue; /* Skip location; no valid chip at this address */
2045                 }
2046                 start = i << cfi->chipshift;
2047                 if (jedec_read_mfr(map, start, cfi) == cfi->mfr &&
2048                     jedec_read_id(map, start, cfi) == cfi->id) {
2049                         /* Eep. This chip also looks like it's in autoselect mode.
2050                            Is it an alias for the new one? */
2051                         jedec_reset(start, map, cfi);
2052
2053                         /* If the device IDs go away, it's an alias */
2054                         if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
2055                             jedec_read_id(map, base, cfi) != cfi->id) {
2056                                 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
2057                                        map->name, base, start);
2058                                 return 0;
2059                         }
2060                         
2061                         /* Yes, it's actually got the device IDs as data. Most
2062                          * unfortunate. Stick the new chip in read mode
2063                          * too and if it's the same, assume it's an alias. */
2064                         /* FIXME: Use other modes to do a proper check */
2065                         jedec_reset(base, map, cfi);
2066                         if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
2067                             jedec_read_id(map, base, cfi) == cfi->id) {
2068                                 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
2069                                        map->name, base, start);
2070                                 return 0;
2071                         }
2072                 }
2073         }
2074                 
2075         /* OK, if we got to here, then none of the previous chips appear to
2076            be aliases for the current one. */
2077         set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
2078         cfi->numchips++;
2079                 
2080 ok_out:
2081         /* Put it back into Read Mode */
2082         jedec_reset(base, map, cfi);
2083
2084         printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
2085                map->name, cfi_interleave(cfi), cfi->device_type*8, base, 
2086                map->bankwidth*8);
2087         
2088         return 1;
2089 }
2090
2091 static struct chip_probe jedec_chip_probe = {
2092         .name = "JEDEC",
2093         .probe_chip = jedec_probe_chip
2094 };
2095
2096 static struct mtd_info *jedec_probe(struct map_info *map)
2097 {
2098         /*
2099          * Just use the generic probe stuff to call our CFI-specific
2100          * chip_probe routine in all the possible permutations, etc.
2101          */
2102         return mtd_do_chip_probe(map, &jedec_chip_probe);
2103 }
2104
2105 static struct mtd_chip_driver jedec_chipdrv = {
2106         .probe  = jedec_probe,
2107         .name   = "jedec_probe",
2108         .module = THIS_MODULE
2109 };
2110
2111 static int __init jedec_probe_init(void)
2112 {
2113         register_mtd_chip_driver(&jedec_chipdrv);
2114         return 0;
2115 }
2116
2117 static void __exit jedec_probe_exit(void)
2118 {
2119         unregister_mtd_chip_driver(&jedec_chipdrv);
2120 }
2121
2122 module_init(jedec_probe_init);
2123 module_exit(jedec_probe_exit);
2124
2125 MODULE_LICENSE("GPL");
2126 MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
2127 MODULE_DESCRIPTION("Probe code for JEDEC-compliant flash chips");