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