2 Common Flash Interface probe code.
3 (C) 2000 Red Hat. GPL'd.
4 $Id: jedec_probe.c,v 1.51 2004/07/14 14:44:30 thayne Exp $
5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
6 for the standard this probe goes back to.
8 Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
11 #include <linux/config.h>
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/types.h>
15 #include <linux/kernel.h>
17 #include <asm/byteorder.h>
18 #include <linux/errno.h>
19 #include <linux/slab.h>
20 #include <linux/interrupt.h>
21 #include <linux/init.h>
23 #include <linux/mtd/mtd.h>
24 #include <linux/mtd/map.h>
25 #include <linux/mtd/cfi.h>
26 #include <linux/mtd/gen_probe.h>
29 #define MANUFACTURER_AMD 0x0001
30 #define MANUFACTURER_ATMEL 0x001f
31 #define MANUFACTURER_FUJITSU 0x0004
32 #define MANUFACTURER_INTEL 0x0089
33 #define MANUFACTURER_MACRONIX 0x00C2
34 #define MANUFACTURER_PMC 0x009D
35 #define MANUFACTURER_SST 0x00BF
36 #define MANUFACTURER_ST 0x0020
37 #define MANUFACTURER_TOSHIBA 0x0098
38 #define MANUFACTURER_WINBOND 0x00da
42 #define AM29DL800BB 0x22C8
43 #define AM29DL800BT 0x224A
45 #define AM29F800BB 0x2258
46 #define AM29F800BT 0x22D6
47 #define AM29LV400BB 0x22BA
48 #define AM29LV400BT 0x22B9
49 #define AM29LV800BB 0x225B
50 #define AM29LV800BT 0x22DA
51 #define AM29LV160DT 0x22C4
52 #define AM29LV160DB 0x2249
53 #define AM29F017D 0x003D
54 #define AM29F016D 0x00AD
55 #define AM29F080 0x00D5
56 #define AM29F040 0x00A4
57 #define AM29LV040B 0x004F
58 #define AM29F032B 0x0041
61 #define AT49BV512 0x0003
62 #define AT29LV512 0x003d
63 #define AT49BV16X 0x00C0
64 #define AT49BV16XT 0x00C2
65 #define AT49BV32X 0x00C8
66 #define AT49BV32XT 0x00C9
69 #define MBM29F040C 0x00A4
70 #define MBM29LV650UE 0x22D7
71 #define MBM29LV320TE 0x22F6
72 #define MBM29LV320BE 0x22F9
73 #define MBM29LV160TE 0x22C4
74 #define MBM29LV160BE 0x2249
75 #define MBM29LV800BA 0x225B
76 #define MBM29LV800TA 0x22DA
77 #define MBM29LV400TC 0x22B9
78 #define MBM29LV400BC 0x22BA
82 #define I28F004B3T 0x00d4
83 #define I28F004B3B 0x00d5
84 #define I28F400B3T 0x8894
85 #define I28F400B3B 0x8895
86 #define I28F008S5 0x00a6
87 #define I28F016S5 0x00a0
88 #define I28F008SA 0x00a2
89 #define I28F008B3T 0x00d2
90 #define I28F008B3B 0x00d3
91 #define I28F800B3T 0x8892
92 #define I28F800B3B 0x8893
93 #define I28F016S3 0x00aa
94 #define I28F016B3T 0x00d0
95 #define I28F016B3B 0x00d1
96 #define I28F160B3T 0x8890
97 #define I28F160B3B 0x8891
98 #define I28F320B3T 0x8896
99 #define I28F320B3B 0x8897
100 #define I28F640B3T 0x8898
101 #define I28F640B3B 0x8899
102 #define I82802AB 0x00ad
103 #define I82802AC 0x00ac
106 #define MX29LV160T 0x22C4
107 #define MX29LV160B 0x2249
108 #define MX29F016 0x00AD
109 #define MX29F004T 0x0045
110 #define MX29F004B 0x0046
113 #define PM49FL002 0x006D
114 #define PM49FL004 0x006E
115 #define PM49FL008 0x006A
117 /* ST - www.st.com */
118 #define M29W800DT 0x00D7
119 #define M29W800DB 0x005B
120 #define M29W160DT 0x22C4
121 #define M29W160DB 0x2249
122 #define M29W040B 0x00E3
123 #define M50FW040 0x002C
124 #define M50FW080 0x002D
125 #define M50FW016 0x002E
128 #define SST29EE020 0x0010
129 #define SST29LE020 0x0012
130 #define SST29EE512 0x005d
131 #define SST29LE512 0x003d
132 #define SST39LF800 0x2781
133 #define SST39LF160 0x2782
134 #define SST39LF512 0x00D4
135 #define SST39LF010 0x00D5
136 #define SST39LF020 0x00D6
137 #define SST39LF040 0x00D7
138 #define SST39SF010A 0x00B5
139 #define SST39SF020A 0x00B6
140 #define SST49LF004B 0x0060
141 #define SST49LF008A 0x005a
142 #define SST49LF030A 0x001C
143 #define SST49LF040A 0x0051
144 #define SST49LF080A 0x005B
147 #define TC58FVT160 0x00C2
148 #define TC58FVB160 0x0043
149 #define TC58FVT321 0x009A
150 #define TC58FVB321 0x009C
151 #define TC58FVT641 0x0093
152 #define TC58FVB641 0x0095
155 #define W49V002A 0x00b0
159 * Unlock address sets for AMD command sets.
160 * Intel command sets use the MTD_UADDR_UNNECESSARY.
161 * Each identifier, except MTD_UADDR_UNNECESSARY, and
162 * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[].
163 * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure
164 * initialization need not require initializing all of the
165 * unlock addresses for all bit widths.
168 MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */
169 MTD_UADDR_0x0555_0x02AA,
170 MTD_UADDR_0x0555_0x0AAA,
171 MTD_UADDR_0x5555_0x2AAA,
172 MTD_UADDR_0x0AAA_0x0555,
173 MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */
174 MTD_UADDR_UNNECESSARY, /* Does not require any address */
185 * I don't like the fact that the first entry in unlock_addrs[]
186 * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
187 * should not be used. The problem is that structures with
188 * initializers have extra fields initialized to 0. It is _very_
189 * desireable to have the unlock address entries for unsupported
190 * data widths automatically initialized - that means that
191 * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
194 static const struct unlock_addr unlock_addrs[] = {
195 [MTD_UADDR_NOT_SUPPORTED] = {
200 [MTD_UADDR_0x0555_0x02AA] = {
205 [MTD_UADDR_0x0555_0x0AAA] = {
210 [MTD_UADDR_0x5555_0x2AAA] = {
215 [MTD_UADDR_0x0AAA_0x0555] = {
220 [MTD_UADDR_DONT_CARE] = {
221 .addr1 = 0x0000, /* Doesn't matter which address */
222 .addr2 = 0x0000 /* is used - must be last entry */
227 struct amd_flash_info {
232 const int NumEraseRegions;
234 const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */
235 const ulong regions[6];
238 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
240 #define SIZE_64KiB 16
241 #define SIZE_128KiB 17
242 #define SIZE_256KiB 18
243 #define SIZE_512KiB 19
251 * Please keep this list ordered by manufacturer!
252 * Fortunately, the list isn't searched often and so a
253 * slow, linear search isn't so bad.
255 static const struct amd_flash_info jedec_table[] = {
257 .mfr_id = MANUFACTURER_AMD,
259 .name = "AMD AM29F032B",
261 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
263 .DevSize = SIZE_4MiB,
264 .CmdSet = P_ID_AMD_STD,
267 ERASEINFO(0x10000,64)
270 .mfr_id = MANUFACTURER_AMD,
271 .dev_id = AM29LV160DT,
272 .name = "AMD AM29LV160DT",
274 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
275 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
277 .DevSize = SIZE_2MiB,
278 .CmdSet = P_ID_AMD_STD,
281 ERASEINFO(0x10000,31),
282 ERASEINFO(0x08000,1),
283 ERASEINFO(0x02000,2),
287 .mfr_id = MANUFACTURER_AMD,
288 .dev_id = AM29LV160DB,
289 .name = "AMD AM29LV160DB",
291 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
292 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
294 .DevSize = SIZE_2MiB,
295 .CmdSet = P_ID_AMD_STD,
298 ERASEINFO(0x04000,1),
299 ERASEINFO(0x02000,2),
300 ERASEINFO(0x08000,1),
301 ERASEINFO(0x10000,31)
304 .mfr_id = MANUFACTURER_AMD,
305 .dev_id = AM29LV400BB,
306 .name = "AMD AM29LV400BB",
308 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
309 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
311 .DevSize = SIZE_512KiB,
312 .CmdSet = P_ID_AMD_STD,
315 ERASEINFO(0x04000,1),
316 ERASEINFO(0x02000,2),
317 ERASEINFO(0x08000,1),
321 .mfr_id = MANUFACTURER_AMD,
322 .dev_id = AM29LV400BT,
323 .name = "AMD AM29LV400BT",
325 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
326 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
328 .DevSize = SIZE_512KiB,
329 .CmdSet = P_ID_AMD_STD,
332 ERASEINFO(0x10000,7),
333 ERASEINFO(0x08000,1),
334 ERASEINFO(0x02000,2),
338 .mfr_id = MANUFACTURER_AMD,
339 .dev_id = AM29LV800BB,
340 .name = "AMD AM29LV800BB",
342 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
343 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
345 .DevSize = SIZE_1MiB,
346 .CmdSet = P_ID_AMD_STD,
349 ERASEINFO(0x04000,1),
350 ERASEINFO(0x02000,2),
351 ERASEINFO(0x08000,1),
352 ERASEINFO(0x10000,15),
356 .mfr_id = MANUFACTURER_AMD,
357 .dev_id = AM29DL800BB,
358 .name = "AMD AM29DL800BB",
360 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
361 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
363 .DevSize = SIZE_1MiB,
364 .CmdSet = P_ID_AMD_STD,
367 ERASEINFO(0x04000,1),
368 ERASEINFO(0x08000,1),
369 ERASEINFO(0x02000,4),
370 ERASEINFO(0x08000,1),
371 ERASEINFO(0x04000,1),
372 ERASEINFO(0x10000,14)
375 .mfr_id = MANUFACTURER_AMD,
376 .dev_id = AM29DL800BT,
377 .name = "AMD AM29DL800BT",
379 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
380 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
382 .DevSize = SIZE_1MiB,
383 .CmdSet = P_ID_AMD_STD,
386 ERASEINFO(0x10000,14),
387 ERASEINFO(0x04000,1),
388 ERASEINFO(0x08000,1),
389 ERASEINFO(0x02000,4),
390 ERASEINFO(0x08000,1),
394 .mfr_id = MANUFACTURER_AMD,
395 .dev_id = AM29F800BB,
396 .name = "AMD AM29F800BB",
398 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
399 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
401 .DevSize = SIZE_1MiB,
402 .CmdSet = P_ID_AMD_STD,
405 ERASEINFO(0x04000,1),
406 ERASEINFO(0x02000,2),
407 ERASEINFO(0x08000,1),
408 ERASEINFO(0x10000,15),
411 .mfr_id = MANUFACTURER_AMD,
412 .dev_id = AM29LV800BT,
413 .name = "AMD AM29LV800BT",
415 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
416 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
418 .DevSize = SIZE_1MiB,
419 .CmdSet = P_ID_AMD_STD,
422 ERASEINFO(0x10000,15),
423 ERASEINFO(0x08000,1),
424 ERASEINFO(0x02000,2),
428 .mfr_id = MANUFACTURER_AMD,
429 .dev_id = AM29F800BT,
430 .name = "AMD AM29F800BT",
432 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
433 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
435 .DevSize = SIZE_1MiB,
436 .CmdSet = P_ID_AMD_STD,
439 ERASEINFO(0x10000,15),
440 ERASEINFO(0x08000,1),
441 ERASEINFO(0x02000,2),
445 .mfr_id = MANUFACTURER_AMD,
447 .name = "AMD AM29F017D",
449 [0] = MTD_UADDR_DONT_CARE /* x8 */
451 .DevSize = SIZE_2MiB,
452 .CmdSet = P_ID_AMD_STD,
455 ERASEINFO(0x10000,32),
458 .mfr_id = MANUFACTURER_AMD,
460 .name = "AMD AM29F016D",
462 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
464 .DevSize = SIZE_2MiB,
465 .CmdSet = P_ID_AMD_STD,
468 ERASEINFO(0x10000,32),
471 .mfr_id = MANUFACTURER_AMD,
473 .name = "AMD AM29F080",
475 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
477 .DevSize = SIZE_1MiB,
478 .CmdSet = P_ID_AMD_STD,
481 ERASEINFO(0x10000,16),
484 .mfr_id = MANUFACTURER_AMD,
486 .name = "AMD AM29F040",
488 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
490 .DevSize = SIZE_512KiB,
491 .CmdSet = P_ID_AMD_STD,
494 ERASEINFO(0x10000,8),
497 .mfr_id = MANUFACTURER_AMD,
498 .dev_id = AM29LV040B,
499 .name = "AMD AM29LV040B",
501 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
503 .DevSize = SIZE_512KiB,
504 .CmdSet = P_ID_AMD_STD,
507 ERASEINFO(0x10000,8),
510 .mfr_id = MANUFACTURER_ATMEL,
512 .name = "Atmel AT49BV512",
514 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
516 .DevSize = SIZE_64KiB,
517 .CmdSet = P_ID_AMD_STD,
523 .mfr_id = MANUFACTURER_ATMEL,
525 .name = "Atmel AT29LV512",
527 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
529 .DevSize = SIZE_64KiB,
530 .CmdSet = P_ID_AMD_STD,
537 .mfr_id = MANUFACTURER_ATMEL,
539 .name = "Atmel AT49BV16X",
541 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
542 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
544 .DevSize = SIZE_2MiB,
545 .CmdSet = P_ID_AMD_STD,
548 ERASEINFO(0x02000,8),
549 ERASEINFO(0x10000,31)
552 .mfr_id = MANUFACTURER_ATMEL,
553 .dev_id = AT49BV16XT,
554 .name = "Atmel AT49BV16XT",
556 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
557 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
559 .DevSize = SIZE_2MiB,
560 .CmdSet = P_ID_AMD_STD,
563 ERASEINFO(0x10000,31),
567 .mfr_id = MANUFACTURER_ATMEL,
569 .name = "Atmel AT49BV32X",
571 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
572 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
574 .DevSize = SIZE_4MiB,
575 .CmdSet = P_ID_AMD_STD,
578 ERASEINFO(0x02000,8),
579 ERASEINFO(0x10000,63)
582 .mfr_id = MANUFACTURER_ATMEL,
583 .dev_id = AT49BV32XT,
584 .name = "Atmel AT49BV32XT",
586 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
587 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
589 .DevSize = SIZE_4MiB,
590 .CmdSet = P_ID_AMD_STD,
593 ERASEINFO(0x10000,63),
597 .mfr_id = MANUFACTURER_FUJITSU,
598 .dev_id = MBM29F040C,
599 .name = "Fujitsu MBM29F040C",
601 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
603 .DevSize = SIZE_512KiB,
604 .CmdSet = P_ID_AMD_STD,
610 .mfr_id = MANUFACTURER_FUJITSU,
611 .dev_id = MBM29LV650UE,
612 .name = "Fujitsu MBM29LV650UE",
614 [0] = MTD_UADDR_DONT_CARE /* x16 */
616 .DevSize = SIZE_8MiB,
617 .CmdSet = P_ID_AMD_STD,
620 ERASEINFO(0x10000,128)
623 .mfr_id = MANUFACTURER_FUJITSU,
624 .dev_id = MBM29LV320TE,
625 .name = "Fujitsu MBM29LV320TE",
627 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
628 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
630 .DevSize = SIZE_4MiB,
631 .CmdSet = P_ID_AMD_STD,
634 ERASEINFO(0x10000,63),
638 .mfr_id = MANUFACTURER_FUJITSU,
639 .dev_id = MBM29LV320BE,
640 .name = "Fujitsu MBM29LV320BE",
642 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
643 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
645 .DevSize = SIZE_4MiB,
646 .CmdSet = P_ID_AMD_STD,
649 ERASEINFO(0x02000,8),
650 ERASEINFO(0x10000,63)
653 .mfr_id = MANUFACTURER_FUJITSU,
654 .dev_id = MBM29LV160TE,
655 .name = "Fujitsu MBM29LV160TE",
657 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
658 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
660 .DevSize = SIZE_2MiB,
661 .CmdSet = P_ID_AMD_STD,
664 ERASEINFO(0x10000,31),
665 ERASEINFO(0x08000,1),
666 ERASEINFO(0x02000,2),
670 .mfr_id = MANUFACTURER_FUJITSU,
671 .dev_id = MBM29LV160BE,
672 .name = "Fujitsu MBM29LV160BE",
674 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
675 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
677 .DevSize = SIZE_2MiB,
678 .CmdSet = P_ID_AMD_STD,
681 ERASEINFO(0x04000,1),
682 ERASEINFO(0x02000,2),
683 ERASEINFO(0x08000,1),
684 ERASEINFO(0x10000,31)
687 .mfr_id = MANUFACTURER_FUJITSU,
688 .dev_id = MBM29LV800BA,
689 .name = "Fujitsu MBM29LV800BA",
691 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
692 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
694 .DevSize = SIZE_1MiB,
695 .CmdSet = P_ID_AMD_STD,
698 ERASEINFO(0x04000,1),
699 ERASEINFO(0x02000,2),
700 ERASEINFO(0x08000,1),
701 ERASEINFO(0x10000,15)
704 .mfr_id = MANUFACTURER_FUJITSU,
705 .dev_id = MBM29LV800TA,
706 .name = "Fujitsu MBM29LV800TA",
708 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
709 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
711 .DevSize = SIZE_1MiB,
712 .CmdSet = P_ID_AMD_STD,
715 ERASEINFO(0x10000,15),
716 ERASEINFO(0x08000,1),
717 ERASEINFO(0x02000,2),
721 .mfr_id = MANUFACTURER_FUJITSU,
722 .dev_id = MBM29LV400BC,
723 .name = "Fujitsu MBM29LV400BC",
725 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
726 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
728 .DevSize = SIZE_512KiB,
729 .CmdSet = P_ID_AMD_STD,
732 ERASEINFO(0x04000,1),
733 ERASEINFO(0x02000,2),
734 ERASEINFO(0x08000,1),
738 .mfr_id = MANUFACTURER_FUJITSU,
739 .dev_id = MBM29LV400TC,
740 .name = "Fujitsu MBM29LV400TC",
742 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
743 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
745 .DevSize = SIZE_512KiB,
746 .CmdSet = P_ID_AMD_STD,
749 ERASEINFO(0x10000,7),
750 ERASEINFO(0x08000,1),
751 ERASEINFO(0x02000,2),
755 .mfr_id = MANUFACTURER_INTEL,
756 .dev_id = I28F004B3B,
757 .name = "Intel 28F004B3B",
759 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
761 .DevSize = SIZE_512KiB,
762 .CmdSet = P_ID_INTEL_STD,
765 ERASEINFO(0x02000, 8),
766 ERASEINFO(0x10000, 7),
769 .mfr_id = MANUFACTURER_INTEL,
770 .dev_id = I28F004B3T,
771 .name = "Intel 28F004B3T",
773 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
775 .DevSize = SIZE_512KiB,
776 .CmdSet = P_ID_INTEL_STD,
779 ERASEINFO(0x10000, 7),
780 ERASEINFO(0x02000, 8),
783 .mfr_id = MANUFACTURER_INTEL,
784 .dev_id = I28F400B3B,
785 .name = "Intel 28F400B3B",
787 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
788 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
790 .DevSize = SIZE_512KiB,
791 .CmdSet = P_ID_INTEL_STD,
794 ERASEINFO(0x02000, 8),
795 ERASEINFO(0x10000, 7),
798 .mfr_id = MANUFACTURER_INTEL,
799 .dev_id = I28F400B3T,
800 .name = "Intel 28F400B3T",
802 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
803 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
805 .DevSize = SIZE_512KiB,
806 .CmdSet = P_ID_INTEL_STD,
809 ERASEINFO(0x10000, 7),
810 ERASEINFO(0x02000, 8),
813 .mfr_id = MANUFACTURER_INTEL,
814 .dev_id = I28F008B3B,
815 .name = "Intel 28F008B3B",
817 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
819 .DevSize = SIZE_1MiB,
820 .CmdSet = P_ID_INTEL_STD,
823 ERASEINFO(0x02000, 8),
824 ERASEINFO(0x10000, 15),
827 .mfr_id = MANUFACTURER_INTEL,
828 .dev_id = I28F008B3T,
829 .name = "Intel 28F008B3T",
831 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
833 .DevSize = SIZE_1MiB,
834 .CmdSet = P_ID_INTEL_STD,
837 ERASEINFO(0x10000, 15),
838 ERASEINFO(0x02000, 8),
841 .mfr_id = MANUFACTURER_INTEL,
843 .name = "Intel 28F008S5",
845 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
847 .DevSize = SIZE_1MiB,
848 .CmdSet = P_ID_INTEL_EXT,
851 ERASEINFO(0x10000,16),
854 .mfr_id = MANUFACTURER_INTEL,
856 .name = "Intel 28F016S5",
858 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
860 .DevSize = SIZE_2MiB,
861 .CmdSet = P_ID_INTEL_EXT,
864 ERASEINFO(0x10000,32),
867 .mfr_id = MANUFACTURER_INTEL,
869 .name = "Intel 28F008SA",
871 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
873 .DevSize = SIZE_1MiB,
874 .CmdSet = P_ID_INTEL_STD,
877 ERASEINFO(0x10000, 16),
880 .mfr_id = MANUFACTURER_INTEL,
881 .dev_id = I28F800B3B,
882 .name = "Intel 28F800B3B",
884 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
886 .DevSize = SIZE_1MiB,
887 .CmdSet = P_ID_INTEL_STD,
890 ERASEINFO(0x02000, 8),
891 ERASEINFO(0x10000, 15),
894 .mfr_id = MANUFACTURER_INTEL,
895 .dev_id = I28F800B3T,
896 .name = "Intel 28F800B3T",
898 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
900 .DevSize = SIZE_1MiB,
901 .CmdSet = P_ID_INTEL_STD,
904 ERASEINFO(0x10000, 15),
905 ERASEINFO(0x02000, 8),
908 .mfr_id = MANUFACTURER_INTEL,
909 .dev_id = I28F016B3B,
910 .name = "Intel 28F016B3B",
912 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
914 .DevSize = SIZE_2MiB,
915 .CmdSet = P_ID_INTEL_STD,
918 ERASEINFO(0x02000, 8),
919 ERASEINFO(0x10000, 31),
922 .mfr_id = MANUFACTURER_INTEL,
924 .name = "Intel I28F016S3",
926 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
928 .DevSize = SIZE_2MiB,
929 .CmdSet = P_ID_INTEL_STD,
932 ERASEINFO(0x10000, 32),
935 .mfr_id = MANUFACTURER_INTEL,
936 .dev_id = I28F016B3T,
937 .name = "Intel 28F016B3T",
939 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
941 .DevSize = SIZE_2MiB,
942 .CmdSet = P_ID_INTEL_STD,
945 ERASEINFO(0x10000, 31),
946 ERASEINFO(0x02000, 8),
949 .mfr_id = MANUFACTURER_INTEL,
950 .dev_id = I28F160B3B,
951 .name = "Intel 28F160B3B",
953 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
955 .DevSize = SIZE_2MiB,
956 .CmdSet = P_ID_INTEL_STD,
959 ERASEINFO(0x02000, 8),
960 ERASEINFO(0x10000, 31),
963 .mfr_id = MANUFACTURER_INTEL,
964 .dev_id = I28F160B3T,
965 .name = "Intel 28F160B3T",
967 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
969 .DevSize = SIZE_2MiB,
970 .CmdSet = P_ID_INTEL_STD,
973 ERASEINFO(0x10000, 31),
974 ERASEINFO(0x02000, 8),
977 .mfr_id = MANUFACTURER_INTEL,
978 .dev_id = I28F320B3B,
979 .name = "Intel 28F320B3B",
981 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
983 .DevSize = SIZE_4MiB,
984 .CmdSet = P_ID_INTEL_STD,
987 ERASEINFO(0x02000, 8),
988 ERASEINFO(0x10000, 63),
991 .mfr_id = MANUFACTURER_INTEL,
992 .dev_id = I28F320B3T,
993 .name = "Intel 28F320B3T",
995 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
997 .DevSize = SIZE_4MiB,
998 .CmdSet = P_ID_INTEL_STD,
1001 ERASEINFO(0x10000, 63),
1002 ERASEINFO(0x02000, 8),
1005 .mfr_id = MANUFACTURER_INTEL,
1006 .dev_id = I28F640B3B,
1007 .name = "Intel 28F640B3B",
1009 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
1011 .DevSize = SIZE_8MiB,
1012 .CmdSet = P_ID_INTEL_STD,
1013 .NumEraseRegions= 2,
1015 ERASEINFO(0x02000, 8),
1016 ERASEINFO(0x10000, 127),
1019 .mfr_id = MANUFACTURER_INTEL,
1020 .dev_id = I28F640B3T,
1021 .name = "Intel 28F640B3T",
1023 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
1025 .DevSize = SIZE_8MiB,
1026 .CmdSet = P_ID_INTEL_STD,
1027 .NumEraseRegions= 2,
1029 ERASEINFO(0x10000, 127),
1030 ERASEINFO(0x02000, 8),
1033 .mfr_id = MANUFACTURER_INTEL,
1035 .name = "Intel 82802AB",
1037 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1039 .DevSize = SIZE_512KiB,
1040 .CmdSet = P_ID_INTEL_EXT,
1041 .NumEraseRegions= 1,
1043 ERASEINFO(0x10000,8),
1046 .mfr_id = MANUFACTURER_INTEL,
1048 .name = "Intel 82802AC",
1050 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1052 .DevSize = SIZE_1MiB,
1053 .CmdSet = P_ID_INTEL_EXT,
1054 .NumEraseRegions= 1,
1056 ERASEINFO(0x10000,16),
1059 .mfr_id = MANUFACTURER_MACRONIX,
1060 .dev_id = MX29LV160T,
1061 .name = "MXIC MX29LV160T",
1063 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1064 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1066 .DevSize = SIZE_2MiB,
1067 .CmdSet = P_ID_AMD_STD,
1068 .NumEraseRegions= 4,
1070 ERASEINFO(0x10000,31),
1071 ERASEINFO(0x08000,1),
1072 ERASEINFO(0x02000,2),
1073 ERASEINFO(0x04000,1)
1076 .mfr_id = MANUFACTURER_MACRONIX,
1077 .dev_id = MX29LV160B,
1078 .name = "MXIC MX29LV160B",
1080 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1081 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1083 .DevSize = SIZE_2MiB,
1084 .CmdSet = P_ID_AMD_STD,
1085 .NumEraseRegions= 4,
1087 ERASEINFO(0x04000,1),
1088 ERASEINFO(0x02000,2),
1089 ERASEINFO(0x08000,1),
1090 ERASEINFO(0x10000,31)
1093 .mfr_id = MANUFACTURER_MACRONIX,
1095 .name = "Macronix MX29F016",
1097 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1099 .DevSize = SIZE_2MiB,
1100 .CmdSet = P_ID_AMD_STD,
1101 .NumEraseRegions= 1,
1103 ERASEINFO(0x10000,32),
1106 .mfr_id = MANUFACTURER_MACRONIX,
1107 .dev_id = MX29F004T,
1108 .name = "Macronix MX29F004T",
1110 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1112 .DevSize = SIZE_512KiB,
1113 .CmdSet = P_ID_AMD_STD,
1114 .NumEraseRegions= 4,
1116 ERASEINFO(0x10000,7),
1117 ERASEINFO(0x08000,1),
1118 ERASEINFO(0x02000,2),
1119 ERASEINFO(0x04000,1),
1122 .mfr_id = MANUFACTURER_MACRONIX,
1123 .dev_id = MX29F004B,
1124 .name = "Macronix MX29F004B",
1126 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1128 .DevSize = SIZE_512KiB,
1129 .CmdSet = P_ID_AMD_STD,
1130 .NumEraseRegions= 4,
1132 ERASEINFO(0x04000,1),
1133 ERASEINFO(0x02000,2),
1134 ERASEINFO(0x08000,1),
1135 ERASEINFO(0x10000,7),
1138 .mfr_id = MANUFACTURER_PMC,
1139 .dev_id = PM49FL002,
1140 .name = "PMC Pm49FL002",
1142 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1144 .DevSize = SIZE_256KiB,
1145 .CmdSet = P_ID_AMD_STD,
1146 .NumEraseRegions= 1,
1148 ERASEINFO( 0x01000, 64 )
1151 .mfr_id = MANUFACTURER_PMC,
1152 .dev_id = PM49FL004,
1153 .name = "PMC Pm49FL004",
1155 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1157 .DevSize = SIZE_512KiB,
1158 .CmdSet = P_ID_AMD_STD,
1159 .NumEraseRegions= 1,
1161 ERASEINFO( 0x01000, 128 )
1164 .mfr_id = MANUFACTURER_PMC,
1165 .dev_id = PM49FL008,
1166 .name = "PMC Pm49FL008",
1168 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1170 .DevSize = SIZE_1MiB,
1171 .CmdSet = P_ID_AMD_STD,
1172 .NumEraseRegions= 1,
1174 ERASEINFO( 0x01000, 256 )
1177 .mfr_id = MANUFACTURER_SST,
1178 .dev_id = SST39LF512,
1179 .name = "SST 39LF512",
1181 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1183 .DevSize = SIZE_64KiB,
1184 .CmdSet = P_ID_AMD_STD,
1185 .NumEraseRegions= 1,
1187 ERASEINFO(0x01000,16),
1190 .mfr_id = MANUFACTURER_SST,
1191 .dev_id = SST39LF010,
1192 .name = "SST 39LF010",
1194 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1196 .DevSize = SIZE_128KiB,
1197 .CmdSet = P_ID_AMD_STD,
1198 .NumEraseRegions= 1,
1200 ERASEINFO(0x01000,32),
1203 .mfr_id = MANUFACTURER_SST,
1204 .dev_id = SST29EE020,
1205 .name = "SST 29EE020",
1207 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1209 .DevSize = SIZE_256KiB,
1210 .CmdSet = P_ID_SST_PAGE,
1211 .NumEraseRegions= 1,
1212 regions: {ERASEINFO(0x01000,64),
1215 .mfr_id = MANUFACTURER_SST,
1216 .dev_id = SST29LE020,
1217 .name = "SST 29LE020",
1219 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1221 .DevSize = SIZE_256KiB,
1222 .CmdSet = P_ID_SST_PAGE,
1223 .NumEraseRegions= 1,
1224 regions: {ERASEINFO(0x01000,64),
1227 .mfr_id = MANUFACTURER_SST,
1228 .dev_id = SST39LF020,
1229 .name = "SST 39LF020",
1231 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1233 .DevSize = SIZE_256KiB,
1234 .CmdSet = P_ID_AMD_STD,
1235 .NumEraseRegions= 1,
1237 ERASEINFO(0x01000,64),
1240 .mfr_id = MANUFACTURER_SST,
1241 .dev_id = SST39LF040,
1242 .name = "SST 39LF040",
1244 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1246 .DevSize = SIZE_512KiB,
1247 .CmdSet = P_ID_AMD_STD,
1248 .NumEraseRegions= 1,
1250 ERASEINFO(0x01000,128),
1253 .mfr_id = MANUFACTURER_SST,
1254 .dev_id = SST39SF010A,
1255 .name = "SST 39SF010A",
1257 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1259 .DevSize = SIZE_128KiB,
1260 .CmdSet = P_ID_AMD_STD,
1261 .NumEraseRegions= 1,
1263 ERASEINFO(0x01000,32),
1266 .mfr_id = MANUFACTURER_SST,
1267 .dev_id = SST39SF020A,
1268 .name = "SST 39SF020A",
1270 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1272 .DevSize = SIZE_256KiB,
1273 .CmdSet = P_ID_AMD_STD,
1274 .NumEraseRegions= 1,
1276 ERASEINFO(0x01000,64),
1279 .mfr_id = MANUFACTURER_SST,
1280 .dev_id = SST49LF004B,
1281 .name = "SST 49LF004B",
1283 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1285 .DevSize = SIZE_512KiB,
1286 .CmdSet = P_ID_AMD_STD,
1287 .NumEraseRegions= 1,
1289 ERASEINFO(0x01000,128),
1292 .mfr_id = MANUFACTURER_SST,
1293 .dev_id = SST49LF008A,
1294 .name = "SST 49LF008A",
1296 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1298 .DevSize = SIZE_1MiB,
1299 .CmdSet = P_ID_AMD_STD,
1300 .NumEraseRegions= 1,
1302 ERASEINFO(0x01000,256),
1305 .mfr_id = MANUFACTURER_SST,
1306 .dev_id = SST49LF030A,
1307 .name = "SST 49LF030A",
1309 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1311 .DevSize = SIZE_512KiB,
1312 .CmdSet = P_ID_AMD_STD,
1313 .NumEraseRegions= 1,
1315 ERASEINFO(0x01000,96),
1318 .mfr_id = MANUFACTURER_SST,
1319 .dev_id = SST49LF040A,
1320 .name = "SST 49LF040A",
1322 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1324 .DevSize = SIZE_512KiB,
1325 .CmdSet = P_ID_AMD_STD,
1326 .NumEraseRegions= 1,
1328 ERASEINFO(0x01000,128),
1331 .mfr_id = MANUFACTURER_SST,
1332 .dev_id = SST49LF080A,
1333 .name = "SST 49LF080A",
1335 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1337 .DevSize = SIZE_1MiB,
1338 .CmdSet = P_ID_AMD_STD,
1339 .NumEraseRegions= 1,
1341 ERASEINFO(0x01000,256),
1344 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1345 .dev_id = M29W800DT,
1346 .name = "ST M29W800DT",
1348 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1349 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1351 .DevSize = SIZE_1MiB,
1352 .CmdSet = P_ID_AMD_STD,
1353 .NumEraseRegions= 4,
1355 ERASEINFO(0x10000,15),
1356 ERASEINFO(0x08000,1),
1357 ERASEINFO(0x02000,2),
1358 ERASEINFO(0x04000,1)
1361 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1362 .dev_id = M29W800DB,
1363 .name = "ST M29W800DB",
1365 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1366 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1368 .DevSize = SIZE_1MiB,
1369 .CmdSet = P_ID_AMD_STD,
1370 .NumEraseRegions= 4,
1372 ERASEINFO(0x04000,1),
1373 ERASEINFO(0x02000,2),
1374 ERASEINFO(0x08000,1),
1375 ERASEINFO(0x10000,15)
1378 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1379 .dev_id = M29W160DT,
1380 .name = "ST M29W160DT",
1382 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1383 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1385 .DevSize = SIZE_2MiB,
1386 .CmdSet = P_ID_AMD_STD,
1387 .NumEraseRegions= 4,
1389 ERASEINFO(0x10000,31),
1390 ERASEINFO(0x08000,1),
1391 ERASEINFO(0x02000,2),
1392 ERASEINFO(0x04000,1)
1395 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1396 .dev_id = M29W160DB,
1397 .name = "ST M29W160DB",
1399 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1400 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1402 .DevSize = SIZE_2MiB,
1403 .CmdSet = P_ID_AMD_STD,
1404 .NumEraseRegions= 4,
1406 ERASEINFO(0x04000,1),
1407 ERASEINFO(0x02000,2),
1408 ERASEINFO(0x08000,1),
1409 ERASEINFO(0x10000,31)
1412 .mfr_id = MANUFACTURER_ST,
1414 .name = "ST M29W040B",
1416 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1418 .DevSize = SIZE_512KiB,
1419 .CmdSet = P_ID_AMD_STD,
1420 .NumEraseRegions= 1,
1422 ERASEINFO(0x10000,8),
1425 .mfr_id = MANUFACTURER_ST,
1427 .name = "ST M50FW040",
1429 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1431 .DevSize = SIZE_512KiB,
1432 .CmdSet = P_ID_INTEL_EXT,
1433 .NumEraseRegions= 1,
1435 ERASEINFO(0x10000,8),
1438 .mfr_id = MANUFACTURER_ST,
1440 .name = "ST M50FW080",
1442 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1444 .DevSize = SIZE_1MiB,
1445 .CmdSet = P_ID_INTEL_EXT,
1446 .NumEraseRegions= 1,
1448 ERASEINFO(0x10000,16),
1451 .mfr_id = MANUFACTURER_ST,
1453 .name = "ST M50FW016",
1455 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1457 .DevSize = SIZE_2MiB,
1458 .CmdSet = P_ID_INTEL_EXT,
1459 .NumEraseRegions= 1,
1461 ERASEINFO(0x10000,32),
1464 .mfr_id = MANUFACTURER_TOSHIBA,
1465 .dev_id = TC58FVT160,
1466 .name = "Toshiba TC58FVT160",
1468 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1469 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1471 .DevSize = SIZE_2MiB,
1472 .CmdSet = P_ID_AMD_STD,
1473 .NumEraseRegions= 4,
1475 ERASEINFO(0x10000,31),
1476 ERASEINFO(0x08000,1),
1477 ERASEINFO(0x02000,2),
1478 ERASEINFO(0x04000,1)
1481 .mfr_id = MANUFACTURER_TOSHIBA,
1482 .dev_id = TC58FVB160,
1483 .name = "Toshiba TC58FVB160",
1485 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1486 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1488 .DevSize = SIZE_2MiB,
1489 .CmdSet = P_ID_AMD_STD,
1490 .NumEraseRegions= 4,
1492 ERASEINFO(0x04000,1),
1493 ERASEINFO(0x02000,2),
1494 ERASEINFO(0x08000,1),
1495 ERASEINFO(0x10000,31)
1498 .mfr_id = MANUFACTURER_TOSHIBA,
1499 .dev_id = TC58FVB321,
1500 .name = "Toshiba TC58FVB321",
1502 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1503 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1505 .DevSize = SIZE_4MiB,
1506 .CmdSet = P_ID_AMD_STD,
1507 .NumEraseRegions= 2,
1509 ERASEINFO(0x02000,8),
1510 ERASEINFO(0x10000,63)
1513 .mfr_id = MANUFACTURER_TOSHIBA,
1514 .dev_id = TC58FVT321,
1515 .name = "Toshiba TC58FVT321",
1517 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1518 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1520 .DevSize = SIZE_4MiB,
1521 .CmdSet = P_ID_AMD_STD,
1522 .NumEraseRegions= 2,
1524 ERASEINFO(0x10000,63),
1525 ERASEINFO(0x02000,8)
1528 .mfr_id = MANUFACTURER_TOSHIBA,
1529 .dev_id = TC58FVB641,
1530 .name = "Toshiba TC58FVB641",
1532 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1533 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1535 .DevSize = SIZE_8MiB,
1536 .CmdSet = P_ID_AMD_STD,
1537 .NumEraseRegions= 2,
1539 ERASEINFO(0x02000,8),
1540 ERASEINFO(0x10000,127)
1543 .mfr_id = MANUFACTURER_TOSHIBA,
1544 .dev_id = TC58FVT641,
1545 .name = "Toshiba TC58FVT641",
1547 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1548 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1550 .DevSize = SIZE_8MiB,
1551 .CmdSet = P_ID_AMD_STD,
1552 .NumEraseRegions= 2,
1554 ERASEINFO(0x10000,127),
1555 ERASEINFO(0x02000,8)
1558 .mfr_id = MANUFACTURER_WINBOND,
1560 .name = "Winbond W49V002A",
1562 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1564 .DevSize = SIZE_256KiB,
1565 .CmdSet = P_ID_AMD_STD,
1566 .NumEraseRegions= 4,
1568 ERASEINFO(0x10000, 3),
1569 ERASEINFO(0x08000, 1),
1570 ERASEINFO(0x02000, 2),
1571 ERASEINFO(0x04000, 1),
1577 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
1579 static int jedec_probe_chip(struct map_info *map, __u32 base,
1580 unsigned long *chip_map, struct cfi_private *cfi);
1582 struct mtd_info *jedec_probe(struct map_info *map);
1584 static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
1585 struct cfi_private *cfi)
1589 mask = (1 << (cfi->device_type * 8)) -1;
1590 result = map_read(map, base);
1591 return result.x[0] & mask;
1594 static inline u32 jedec_read_id(struct map_info *map, __u32 base,
1595 struct cfi_private *cfi)
1600 osf = cfi->interleave *cfi->device_type;
1601 mask = (1 << (cfi->device_type * 8)) -1;
1602 result = map_read(map, base + osf);
1603 return result.x[0] & mask;
1606 static inline void jedec_reset(u32 base, struct map_info *map,
1607 struct cfi_private *cfi)
1611 /* after checking the datasheets for SST, MACRONIX and ATMEL
1612 * (oh and incidentaly the jedec spec - 3.5.3.3) the reset
1613 * sequence is *supposed* to be 0xaa at 0x5555, 0x55 at
1614 * 0x2aaa, 0xF0 at 0x5555 this will not affect the AMD chips
1615 * as they will ignore the writes and dont care what address
1616 * the F0 is written to */
1617 if(cfi->addr_unlock1) {
1618 /*printk("reset unlock called %x %x \n",cfi->addr_unlock1,cfi->addr_unlock2);*/
1619 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1620 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1623 cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1624 /* Some misdesigned intel chips do not respond for 0xF0 for a reset,
1625 * so ensure we're in read mode. Send both the Intel and the AMD command
1626 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
1627 * this should be safe.
1629 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
1630 /* FIXME - should have reset delay before continuing */
1634 static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type)
1637 __u8 uaddr = MTD_UADDR_NOT_SUPPORTED;
1639 switch ( device_type ) {
1640 case CFI_DEVICETYPE_X8: uaddr_idx = 0; break;
1641 case CFI_DEVICETYPE_X16: uaddr_idx = 1; break;
1642 case CFI_DEVICETYPE_X32: uaddr_idx = 2; break;
1644 printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n",
1645 __func__, device_type);
1649 uaddr = finfo->uaddr[uaddr_idx];
1651 if (uaddr != MTD_UADDR_NOT_SUPPORTED ) {
1652 /* ASSERT("The unlock addresses for non-8-bit mode
1653 are bollocks. We don't really need an array."); */
1654 uaddr = finfo->uaddr[0];
1662 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1664 int i,num_erase_regions;
1668 printk("Found: %s\n",jedec_table[index].name);
1670 num_erase_regions = jedec_table[index].NumEraseRegions;
1672 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
1674 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
1678 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
1680 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
1681 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
1682 p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
1683 p_cfi->cfi_mode = CFI_MODE_JEDEC;
1685 for (i=0; i<num_erase_regions; i++){
1686 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
1688 p_cfi->cmdset_priv = NULL;
1690 /* This may be redundant for some cases, but it doesn't hurt */
1691 p_cfi->mfr = jedec_table[index].mfr_id;
1692 p_cfi->id = jedec_table[index].dev_id;
1694 uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type);
1695 if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
1696 kfree( p_cfi->cfiq );
1700 /* Mask out address bits which are smaller than the device type */
1701 mask = ~(p_cfi->device_type-1);
1702 p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 & mask;
1703 p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 & mask;
1710 * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing
1711 * the mapped address, unlock addresses, and proper chip ID. This function
1712 * attempts to minimize errors. It is doubtfull that this probe will ever
1713 * be perfect - consequently there should be some module parameters that
1714 * could be manually specified to force the chip info.
1716 static inline int jedec_match( __u32 base,
1717 struct map_info *map,
1718 struct cfi_private *cfi,
1719 const struct amd_flash_info *finfo )
1721 int rc = 0; /* failure until all tests pass */
1727 * The IDs must match. For X16 and X32 devices operating in
1728 * a lower width ( X8 or X16 ), the device ID's are usually just
1729 * the lower byte(s) of the larger device ID for wider mode. If
1730 * a part is found that doesn't fit this assumption (device id for
1731 * smaller width mode is completely unrealated to full-width mode)
1732 * then the jedec_table[] will have to be augmented with the IDs
1733 * for different widths.
1735 switch (cfi->device_type) {
1736 case CFI_DEVICETYPE_X8:
1737 mfr = (__u8)finfo->mfr_id;
1738 id = (__u8)finfo->dev_id;
1740 case CFI_DEVICETYPE_X16:
1741 mfr = (__u16)finfo->mfr_id;
1742 id = (__u16)finfo->dev_id;
1744 case CFI_DEVICETYPE_X32:
1745 mfr = (__u16)finfo->mfr_id;
1746 id = (__u32)finfo->dev_id;
1750 "MTD %s(): Unsupported device type %d\n",
1751 __func__, cfi->device_type);
1754 if ( cfi->mfr != mfr || cfi->id != id ) {
1758 /* the part size must fit in the memory window */
1759 DEBUG( MTD_DEBUG_LEVEL3,
1760 "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
1761 __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
1762 if ( base + cfi->interleave * ( 1 << finfo->DevSize ) > map->size ) {
1763 DEBUG( MTD_DEBUG_LEVEL3,
1764 "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
1765 __func__, finfo->mfr_id, finfo->dev_id,
1766 1 << finfo->DevSize );
1770 uaddr = finfo_uaddr(finfo, cfi->device_type);
1771 if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
1775 mask = ~(cfi->device_type-1);
1777 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
1778 __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
1779 if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
1780 && ( (unlock_addrs[uaddr].addr1 & mask) != cfi->addr_unlock1 ||
1781 (unlock_addrs[uaddr].addr2 & mask) != cfi->addr_unlock2 ) ) {
1782 DEBUG( MTD_DEBUG_LEVEL3,
1783 "MTD %s(): 0x%.4lx 0x%.4lx did not match\n",
1785 unlock_addrs[uaddr].addr1 & mask,
1786 unlock_addrs[uaddr].addr2 & mask);
1791 * Make sure the ID's dissappear when the device is taken out of
1792 * ID mode. The only time this should fail when it should succeed
1793 * is when the ID's are written as data to the same
1794 * addresses. For this rare and unfortunate case the chip
1795 * cannot be probed correctly.
1796 * FIXME - write a driver that takes all of the chip info as
1797 * module parameters, doesn't probe but forces a load.
1799 DEBUG( MTD_DEBUG_LEVEL3,
1800 "MTD %s(): check ID's disappear when not in ID mode\n",
1802 jedec_reset( base, map, cfi );
1803 mfr = jedec_read_mfr( map, base, cfi );
1804 id = jedec_read_id( map, base, cfi );
1805 if ( mfr == cfi->mfr && id == cfi->id ) {
1806 DEBUG( MTD_DEBUG_LEVEL3,
1807 "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
1808 "You might need to manually specify JEDEC parameters.\n",
1809 __func__, cfi->mfr, cfi->id );
1813 /* all tests passed - mark as success */
1817 * Put the device back in ID mode - only need to do this if we
1818 * were truly frobbing a real device.
1820 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
1821 if(cfi->addr_unlock1) {
1822 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1823 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1825 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1826 /* FIXME - should have a delay before continuing */
1833 static int jedec_probe_chip(struct map_info *map, __u32 base,
1834 unsigned long *chip_map, struct cfi_private *cfi)
1837 enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED;
1840 if (!cfi->numchips) {
1841 unsigned long mask = ~(cfi->device_type-1);
1845 if (MTD_UADDR_UNNECESSARY == uaddr_idx)
1848 /* Mask out address bits which are smaller than the device type */
1849 cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1 & mask;
1850 cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2 & mask;
1853 /* Make certain we aren't probing past the end of map */
1854 if (base >= map->size) {
1856 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
1857 base, map->size -1);
1861 if ((base + cfi->addr_unlock1) >= map->size) {
1863 "Probe at addr_unlock1(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n",
1864 base, cfi->addr_unlock1, map->size -1);
1868 if ((base + cfi->addr_unlock2) >= map->size) {
1870 "Probe at addr_unlock2(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n",
1871 base, cfi->addr_unlock2, map->size -1);
1877 jedec_reset(base, map, cfi);
1879 /* Autoselect Mode */
1880 if(cfi->addr_unlock1) {
1881 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1882 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1884 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1885 /* FIXME - should have a delay before continuing */
1887 if (!cfi->numchips) {
1888 /* This is the first time we're called. Set up the CFI
1889 stuff accordingly and return */
1891 cfi->mfr = jedec_read_mfr(map, base, cfi);
1892 cfi->id = jedec_read_id(map, base, cfi);
1893 DEBUG(MTD_DEBUG_LEVEL3,
1894 "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
1895 cfi->mfr, cfi->id, cfi->interleave, cfi->device_type);
1896 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
1897 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
1898 DEBUG( MTD_DEBUG_LEVEL3,
1899 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
1900 __func__, cfi->mfr, cfi->id,
1901 cfi->addr_unlock1, cfi->addr_unlock2 );
1902 if (!cfi_jedec_setup(cfi, i))
1912 /* Make sure it is a chip of the same manufacturer and id */
1913 mfr = jedec_read_mfr(map, base, cfi);
1914 id = jedec_read_id(map, base, cfi);
1916 if ((mfr != cfi->mfr) || (id != cfi->id)) {
1917 printk(KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n",
1918 map->name, mfr, id, base);
1919 jedec_reset(base, map, cfi);
1924 /* Check each previous chip locations to see if it's an alias */
1925 for (i=0; i < (base >> cfi->chipshift); i++) {
1926 unsigned long start;
1927 if(!test_bit(i, chip_map)) {
1928 continue; /* Skip location; no valid chip at this address */
1930 start = i << cfi->chipshift;
1931 if (jedec_read_mfr(map, start, cfi) == cfi->mfr &&
1932 jedec_read_id(map, start, cfi) == cfi->id) {
1933 /* Eep. This chip also looks like it's in autoselect mode.
1934 Is it an alias for the new one? */
1935 jedec_reset(start, map, cfi);
1937 /* If the device IDs go away, it's an alias */
1938 if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
1939 jedec_read_id(map, base, cfi) != cfi->id) {
1940 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
1941 map->name, base, start);
1945 /* Yes, it's actually got the device IDs as data. Most
1946 * unfortunate. Stick the new chip in read mode
1947 * too and if it's the same, assume it's an alias. */
1948 /* FIXME: Use other modes to do a proper check */
1949 jedec_reset(base, map, cfi);
1950 if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
1951 jedec_read_id(map, base, cfi) == cfi->id) {
1952 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
1953 map->name, base, start);
1959 /* OK, if we got to here, then none of the previous chips appear to
1960 be aliases for the current one. */
1961 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
1965 /* Put it back into Read Mode */
1966 jedec_reset(base, map, cfi);
1968 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
1969 map->name, cfi->interleave, cfi->device_type*8, base,
1975 static struct chip_probe jedec_chip_probe = {
1977 .probe_chip = jedec_probe_chip
1980 struct mtd_info *jedec_probe(struct map_info *map)
1983 * Just use the generic probe stuff to call our CFI-specific
1984 * chip_probe routine in all the possible permutations, etc.
1986 return mtd_do_chip_probe(map, &jedec_chip_probe);
1989 static struct mtd_chip_driver jedec_chipdrv = {
1990 .probe = jedec_probe,
1991 .name = "jedec_probe",
1992 .module = THIS_MODULE
1995 int __init jedec_probe_init(void)
1997 register_mtd_chip_driver(&jedec_chipdrv);
2001 static void __exit jedec_probe_exit(void)
2003 unregister_mtd_chip_driver(&jedec_chipdrv);
2006 module_init(jedec_probe_init);
2007 module_exit(jedec_probe_exit);
2009 MODULE_LICENSE("GPL");
2010 MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
2011 MODULE_DESCRIPTION("Probe code for JEDEC-compliant flash chips");