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