2 Common Flash Interface probe code.
3 (C) 2000 Red Hat. GPL'd.
4 $Id: jedec_probe.c,v 1.29 2003/05/28 13:57:46 dwmw2 Exp $
5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
6 for the standard this probe goes back to.
9 #include <linux/config.h>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
15 #include <asm/byteorder.h>
16 #include <linux/errno.h>
17 #include <linux/slab.h>
18 #include <linux/interrupt.h>
19 #include <linux/init.h>
21 #include <linux/mtd/mtd.h>
22 #include <linux/mtd/map.h>
23 #include <linux/mtd/cfi.h>
24 #include <linux/mtd/gen_probe.h>
27 #define MANUFACTURER_AMD 0x0001
28 #define MANUFACTURER_ATMEL 0x001f
29 #define MANUFACTURER_FUJITSU 0x0004
30 #define MANUFACTURER_INTEL 0x0089
31 #define MANUFACTURER_MACRONIX 0x00C2
32 #define MANUFACTURER_PMC 0x009D
33 #define MANUFACTURER_SST 0x00BF
34 #define MANUFACTURER_ST 0x0020
35 #define MANUFACTURER_TOSHIBA 0x0098
36 #define MANUFACTURER_WINBOND 0x00da
40 #define AM29F800BB 0x2258
41 #define AM29F800BT 0x22D6
42 #define AM29LV800BB 0x225B
43 #define AM29LV800BT 0x22DA
44 #define AM29LV160DT 0x22C4
45 #define AM29LV160DB 0x2249
46 #define AM29F017D 0x003D
47 #define AM29F016D 0x00AD
48 #define AM29F080 0x00D5
49 #define AM29F040 0x00A4
50 #define AM29LV040B 0x004F
51 #define AM29F032B 0x0041
54 #define AT49BV512 0x0003
55 #define AT29LV512 0x003d
56 #define AT49BV16X 0x00C0
57 #define AT49BV16XT 0x00C2
58 #define AT49BV32X 0x00C8
59 #define AT49BV32XT 0x00C9
62 #define MBM29LV650UE 0x22D7
63 #define MBM29LV320TE 0x22F6
64 #define MBM29LV320BE 0x22F9
65 #define MBM29LV160TE 0x22C4
66 #define MBM29LV160BE 0x2249
67 #define MBM29LV800BA 0x225B
68 #define MBM29LV800TA 0x22DA
71 #define I28F004B3T 0x00d4
72 #define I28F004B3B 0x00d5
73 #define I28F400B3T 0x8894
74 #define I28F400B3B 0x8895
75 #define I28F008S5 0x00a6
76 #define I28F016S5 0x00a0
77 #define I28F008SA 0x00a2
78 #define I28F008B3T 0x00d2
79 #define I28F008B3B 0x00d3
80 #define I28F800B3T 0x8892
81 #define I28F800B3B 0x8893
82 #define I28F016S3 0x00aa
83 #define I28F016B3T 0x00d0
84 #define I28F016B3B 0x00d1
85 #define I28F160B3T 0x8890
86 #define I28F160B3B 0x8891
87 #define I28F320B3T 0x8896
88 #define I28F320B3B 0x8897
89 #define I28F640B3T 0x8898
90 #define I28F640B3B 0x8899
91 #define I82802AB 0x00ad
92 #define I82802AC 0x00ac
95 #define MX29LV160T 0x22C4
96 #define MX29LV160B 0x2249
97 #define MX29F016 0x00AD
98 #define MX29F004T 0x0045
99 #define MX29F004B 0x0046
102 #define PM49FL002 0x006D
103 #define PM49FL004 0x006E
104 #define PM49FL008 0x006A
106 /* ST - www.st.com */
107 #define M29W800DT 0x00D7
108 #define M29W800DB 0x005B
109 #define M29W160DT 0x22C4
110 #define M29W160DB 0x2249
111 #define M29W040B 0x00E3
114 #define SST29EE512 0x005d
115 #define SST29LE512 0x003d
116 #define SST39LF800 0x2781
117 #define SST39LF160 0x2782
118 #define SST39LF512 0x00D4
119 #define SST39LF010 0x00D5
120 #define SST39LF020 0x00D6
121 #define SST39LF040 0x00D7
122 #define SST39SF010A 0x00B5
123 #define SST39SF020A 0x00B6
124 #define SST49LF030A 0x001C
125 #define SST49LF040A 0x0051
126 #define SST49LF080A 0x005B
129 #define TC58FVT160 0x00C2
130 #define TC58FVB160 0x0043
131 #define TC58FVT321 0x009A
132 #define TC58FVB321 0x009C
133 #define TC58FVT641 0x0093
134 #define TC58FVB641 0x0095
137 #define W49V002A 0x00b0
141 * Unlock address sets for AMD command sets.
142 * Intel command sets use the MTD_UADDR_UNNECESSARY.
143 * Each identifier, except MTD_UADDR_UNNECESSARY, and
144 * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[].
145 * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure
146 * initialization need not require initializing all of the
147 * unlock addresses for all bit widths.
150 MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */
151 MTD_UADDR_0x0555_0x02AA,
152 MTD_UADDR_0x0555_0x0AAA,
153 MTD_UADDR_0x5555_0x2AAA,
154 MTD_UADDR_0x0AAA_0x0555,
155 MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */
156 MTD_UADDR_UNNECESSARY, /* Does not require any address */
167 * I don't like the fact that the first entry in unlock_addrs[]
168 * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
169 * should not be used. The problem is that structures with
170 * initializers have extra fields initialized to 0. It is _very_
171 * desireable to have the unlock address entries for unsupported
172 * data widths automatically initialized - that means that
173 * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
176 static const struct unlock_addr unlock_addrs[] = {
177 [MTD_UADDR_NOT_SUPPORTED] = {
182 [MTD_UADDR_0x0555_0x02AA] = {
187 [MTD_UADDR_0x0555_0x0AAA] = {
192 [MTD_UADDR_0x5555_0x2AAA] = {
197 [MTD_UADDR_0x0AAA_0x0555] = {
202 [MTD_UADDR_DONT_CARE] = {
203 .addr1 = 0x0000, /* Doesn't matter which address */
204 .addr2 = 0x0000 /* is used - must be last entry */
209 struct amd_flash_info {
214 const int InterfaceDesc;
215 const int NumEraseRegions;
217 const __u8 uaddr[3]; /* unlock addrs for 8, 16, 32 modes */
218 const ulong regions[4];
221 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
223 #define SIZE_64KiB 16
224 #define SIZE_128KiB 17
225 #define SIZE_256KiB 18
226 #define SIZE_512KiB 19
234 * Please keep this list ordered by manufacturer!
235 * Fortunately, the list isn't searched often and so a
236 * slow, linear search isn't so bad.
238 static const struct amd_flash_info jedec_table[] = {
240 .mfr_id = MANUFACTURER_AMD,
242 .name = "AMD AM29F032B",
244 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
246 .DevSize = SIZE_4MiB,
247 .CmdSet = P_ID_AMD_STD,
250 ERASEINFO(0x10000,64)
253 .mfr_id = MANUFACTURER_AMD,
254 .dev_id = AM29LV160DT,
255 .name = "AMD AM29LV160DT",
257 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
258 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
260 .DevSize = SIZE_2MiB,
261 .CmdSet = P_ID_AMD_STD,
264 ERASEINFO(0x10000,31),
265 ERASEINFO(0x08000,1),
266 ERASEINFO(0x02000,2),
270 .mfr_id = MANUFACTURER_AMD,
271 .dev_id = AM29LV160DB,
272 .name = "AMD AM29LV160DB",
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(0x04000,1),
282 ERASEINFO(0x02000,2),
283 ERASEINFO(0x08000,1),
284 ERASEINFO(0x10000,31)
287 .mfr_id = MANUFACTURER_AMD,
288 .dev_id = AM29LV800BB,
289 .name = "AMD AM29LV800BB",
291 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
292 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
294 .DevSize = SIZE_1MiB,
295 .CmdSet = P_ID_AMD_STD,
298 ERASEINFO(0x04000,1),
299 ERASEINFO(0x02000,2),
300 ERASEINFO(0x08000,1),
301 ERASEINFO(0x10000,15),
304 .mfr_id = MANUFACTURER_AMD,
305 .dev_id = AM29F800BB,
306 .name = "AMD AM29F800BB",
308 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
309 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
311 .DevSize = SIZE_1MiB,
312 .CmdSet = P_ID_AMD_STD,
315 ERASEINFO(0x04000,1),
316 ERASEINFO(0x02000,2),
317 ERASEINFO(0x08000,1),
318 ERASEINFO(0x10000,15),
321 .mfr_id = MANUFACTURER_AMD,
322 .dev_id = AM29LV800BT,
323 .name = "AMD AM29LV800BT",
325 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
326 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
328 .DevSize = SIZE_1MiB,
329 .CmdSet = P_ID_AMD_STD,
332 ERASEINFO(0x10000,15),
333 ERASEINFO(0x08000,1),
334 ERASEINFO(0x02000,2),
338 .mfr_id = MANUFACTURER_AMD,
339 .dev_id = AM29F800BT,
340 .name = "AMD AM29F800BT",
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(0x10000,15),
350 ERASEINFO(0x08000,1),
351 ERASEINFO(0x02000,2),
355 .mfr_id = MANUFACTURER_AMD,
357 .name = "AMD AM29F017D",
359 [0] = MTD_UADDR_DONT_CARE /* x8 */
361 .DevSize = SIZE_2MiB,
362 .CmdSet = P_ID_AMD_STD,
365 ERASEINFO(0x10000,32),
368 .mfr_id = MANUFACTURER_AMD,
370 .name = "AMD AM29F016D",
372 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
374 .DevSize = SIZE_2MiB,
375 .CmdSet = P_ID_AMD_STD,
378 ERASEINFO(0x10000,32),
381 .mfr_id = MANUFACTURER_AMD,
383 .name = "AMD AM29F080",
385 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
387 .DevSize = SIZE_1MiB,
388 .CmdSet = P_ID_AMD_STD,
391 ERASEINFO(0x10000,16),
394 .mfr_id = MANUFACTURER_AMD,
396 .name = "AMD AM29F040",
398 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
400 .DevSize = SIZE_512KiB,
401 .CmdSet = P_ID_AMD_STD,
404 ERASEINFO(0x10000,8),
407 .mfr_id = MANUFACTURER_AMD,
408 .dev_id = AM29LV040B,
409 .name = "AMD AM29LV040B",
411 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
413 .DevSize = SIZE_512KiB,
414 .CmdSet = P_ID_AMD_STD,
417 ERASEINFO(0x10000,8),
420 .mfr_id = MANUFACTURER_ATMEL,
422 .name = "Atmel AT49BV512",
424 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
426 .DevSize = SIZE_64KiB,
427 .CmdSet = P_ID_AMD_STD,
433 .mfr_id = MANUFACTURER_ATMEL,
435 .name = "Atmel AT29LV512",
437 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
439 .DevSize = SIZE_64KiB,
440 .CmdSet = P_ID_AMD_STD,
447 .mfr_id = MANUFACTURER_ATMEL,
449 .name = "Atmel AT49BV16X",
451 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
452 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
454 .DevSize = SIZE_2MiB,
455 .CmdSet = P_ID_AMD_STD,
458 ERASEINFO(0x02000,8),
459 ERASEINFO(0x10000,31)
462 .mfr_id = MANUFACTURER_ATMEL,
463 .dev_id = AT49BV16XT,
464 .name = "Atmel AT49BV16XT",
466 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
467 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
469 .DevSize = SIZE_2MiB,
470 .CmdSet = P_ID_AMD_STD,
473 ERASEINFO(0x10000,31),
477 .mfr_id = MANUFACTURER_ATMEL,
479 .name = "Atmel AT49BV32X",
481 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
482 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
484 .DevSize = SIZE_4MiB,
485 .CmdSet = P_ID_AMD_STD,
488 ERASEINFO(0x02000,8),
489 ERASEINFO(0x10000,63)
492 .mfr_id = MANUFACTURER_ATMEL,
493 .dev_id = AT49BV32XT,
494 .name = "Atmel AT49BV32XT",
496 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
497 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
499 .DevSize = SIZE_4MiB,
500 .CmdSet = P_ID_AMD_STD,
503 ERASEINFO(0x10000,63),
507 .mfr_id = MANUFACTURER_FUJITSU,
508 .dev_id = MBM29LV650UE,
509 .name = "Fujitsu MBM29LV650UE",
511 [0] = MTD_UADDR_DONT_CARE /* x16 */
513 .DevSize = SIZE_8MiB,
514 .CmdSet = P_ID_AMD_STD,
517 ERASEINFO(0x10000,128)
520 .mfr_id = MANUFACTURER_FUJITSU,
521 .dev_id = MBM29LV320TE,
522 .name = "Fujitsu MBM29LV320TE",
524 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
525 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
527 .DevSize = SIZE_4MiB,
528 .CmdSet = P_ID_AMD_STD,
531 ERASEINFO(0x10000,63),
535 .mfr_id = MANUFACTURER_FUJITSU,
536 .dev_id = MBM29LV320BE,
537 .name = "Fujitsu MBM29LV320BE",
539 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
540 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
542 .DevSize = SIZE_4MiB,
543 .CmdSet = P_ID_AMD_STD,
546 ERASEINFO(0x02000,8),
547 ERASEINFO(0x10000,63)
550 .mfr_id = MANUFACTURER_FUJITSU,
551 .dev_id = MBM29LV160TE,
552 .name = "Fujitsu MBM29LV160TE",
554 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
555 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
557 .DevSize = SIZE_2MiB,
558 .CmdSet = P_ID_AMD_STD,
561 ERASEINFO(0x10000,31),
562 ERASEINFO(0x08000,1),
563 ERASEINFO(0x02000,2),
567 .mfr_id = MANUFACTURER_FUJITSU,
568 .dev_id = MBM29LV160BE,
569 .name = "Fujitsu MBM29LV160BE",
571 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
572 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
574 .DevSize = SIZE_2MiB,
575 .CmdSet = P_ID_AMD_STD,
578 ERASEINFO(0x04000,1),
579 ERASEINFO(0x02000,2),
580 ERASEINFO(0x08000,1),
581 ERASEINFO(0x10000,31)
584 .mfr_id = MANUFACTURER_FUJITSU,
585 .dev_id = MBM29LV800BA,
586 .name = "Fujitsu MBM29LV800BA",
588 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
589 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
591 .DevSize = SIZE_1MiB,
592 .CmdSet = P_ID_AMD_STD,
595 ERASEINFO(0x04000,1),
596 ERASEINFO(0x02000,2),
597 ERASEINFO(0x08000,1),
598 ERASEINFO(0x10000,15)
601 .mfr_id = MANUFACTURER_FUJITSU,
602 .dev_id = MBM29LV800TA,
603 .name = "Fujitsu MBM29LV800TA",
605 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
606 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
608 .DevSize = SIZE_1MiB,
609 .CmdSet = P_ID_AMD_STD,
612 ERASEINFO(0x10000,15),
613 ERASEINFO(0x08000,1),
614 ERASEINFO(0x02000,2),
618 .mfr_id = MANUFACTURER_INTEL,
619 .dev_id = I28F004B3B,
620 .name = "Intel 28F004B3B",
622 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
624 .DevSize = SIZE_512KiB,
625 .CmdSet = P_ID_INTEL_STD,
628 ERASEINFO(0x02000, 8),
629 ERASEINFO(0x10000, 7),
632 .mfr_id = MANUFACTURER_INTEL,
633 .dev_id = I28F004B3T,
634 .name = "Intel 28F004B3T",
636 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
638 .DevSize = SIZE_512KiB,
639 .CmdSet = P_ID_INTEL_STD,
642 ERASEINFO(0x10000, 7),
643 ERASEINFO(0x02000, 8),
646 .mfr_id = MANUFACTURER_INTEL,
647 .dev_id = I28F400B3B,
648 .name = "Intel 28F400B3B",
650 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
651 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
653 .DevSize = SIZE_512KiB,
654 .CmdSet = P_ID_INTEL_STD,
657 ERASEINFO(0x02000, 8),
658 ERASEINFO(0x10000, 7),
661 .mfr_id = MANUFACTURER_INTEL,
662 .dev_id = I28F400B3T,
663 .name = "Intel 28F400B3T",
665 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
666 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
668 .DevSize = SIZE_512KiB,
669 .CmdSet = P_ID_INTEL_STD,
672 ERASEINFO(0x10000, 7),
673 ERASEINFO(0x02000, 8),
676 .mfr_id = MANUFACTURER_INTEL,
677 .dev_id = I28F008B3B,
678 .name = "Intel 28F008B3B",
680 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
682 .DevSize = SIZE_1MiB,
683 .CmdSet = P_ID_INTEL_STD,
686 ERASEINFO(0x02000, 8),
687 ERASEINFO(0x10000, 15),
690 .mfr_id = MANUFACTURER_INTEL,
691 .dev_id = I28F008B3T,
692 .name = "Intel 28F008B3T",
694 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
696 .DevSize = SIZE_1MiB,
697 .CmdSet = P_ID_INTEL_STD,
700 ERASEINFO(0x10000, 15),
701 ERASEINFO(0x02000, 8),
704 .mfr_id = MANUFACTURER_INTEL,
706 .name = "Intel 28F008S5",
708 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
710 .DevSize = SIZE_1MiB,
711 .CmdSet = P_ID_INTEL_EXT,
714 ERASEINFO(0x10000,16),
717 .mfr_id = MANUFACTURER_INTEL,
719 .name = "Intel 28F016S5",
721 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
723 .DevSize = SIZE_2MiB,
724 .CmdSet = P_ID_INTEL_EXT,
727 ERASEINFO(0x10000,32),
730 .mfr_id = MANUFACTURER_INTEL,
732 .name = "Intel 28F008SA",
734 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
736 .DevSize = SIZE_1MiB,
737 .CmdSet = P_ID_INTEL_STD,
740 ERASEINFO(0x10000, 16),
743 .mfr_id = MANUFACTURER_INTEL,
744 .dev_id = I28F800B3B,
745 .name = "Intel 28F800B3B",
747 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
749 .DevSize = SIZE_1MiB,
750 .CmdSet = P_ID_INTEL_STD,
753 ERASEINFO(0x02000, 8),
754 ERASEINFO(0x10000, 15),
757 .mfr_id = MANUFACTURER_INTEL,
758 .dev_id = I28F800B3T,
759 .name = "Intel 28F800B3T",
761 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
763 .DevSize = SIZE_1MiB,
764 .CmdSet = P_ID_INTEL_STD,
767 ERASEINFO(0x10000, 15),
768 ERASEINFO(0x02000, 8),
771 .mfr_id = MANUFACTURER_INTEL,
772 .dev_id = I28F016B3B,
773 .name = "Intel 28F016B3B",
775 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
777 .DevSize = SIZE_2MiB,
778 .CmdSet = P_ID_INTEL_STD,
781 ERASEINFO(0x02000, 8),
782 ERASEINFO(0x10000, 31),
785 .mfr_id = MANUFACTURER_INTEL,
787 .name = "Intel I28F016S3",
789 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
791 .DevSize = SIZE_2MiB,
792 .CmdSet = P_ID_INTEL_STD,
795 ERASEINFO(0x10000, 32),
798 .mfr_id = MANUFACTURER_INTEL,
799 .dev_id = I28F016B3T,
800 .name = "Intel 28F016B3T",
802 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
804 .DevSize = SIZE_2MiB,
805 .CmdSet = P_ID_INTEL_STD,
808 ERASEINFO(0x10000, 31),
809 ERASEINFO(0x02000, 8),
812 .mfr_id = MANUFACTURER_INTEL,
813 .dev_id = I28F160B3B,
814 .name = "Intel 28F160B3B",
816 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
818 .DevSize = SIZE_2MiB,
819 .CmdSet = P_ID_INTEL_STD,
822 ERASEINFO(0x02000, 8),
823 ERASEINFO(0x10000, 31),
826 .mfr_id = MANUFACTURER_INTEL,
827 .dev_id = I28F160B3T,
828 .name = "Intel 28F160B3T",
830 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
832 .DevSize = SIZE_2MiB,
833 .CmdSet = P_ID_INTEL_STD,
836 ERASEINFO(0x10000, 31),
837 ERASEINFO(0x02000, 8),
840 .mfr_id = MANUFACTURER_INTEL,
841 .dev_id = I28F320B3B,
842 .name = "Intel 28F320B3B",
844 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
846 .DevSize = SIZE_4MiB,
847 .CmdSet = P_ID_INTEL_STD,
850 ERASEINFO(0x02000, 8),
851 ERASEINFO(0x10000, 63),
854 .mfr_id = MANUFACTURER_INTEL,
855 .dev_id = I28F320B3T,
856 .name = "Intel 28F320B3T",
858 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
860 .DevSize = SIZE_4MiB,
861 .CmdSet = P_ID_INTEL_STD,
864 ERASEINFO(0x10000, 63),
865 ERASEINFO(0x02000, 8),
868 .mfr_id = MANUFACTURER_INTEL,
869 .dev_id = I28F640B3B,
870 .name = "Intel 28F640B3B",
872 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
874 .DevSize = SIZE_8MiB,
875 .CmdSet = P_ID_INTEL_STD,
878 ERASEINFO(0x02000, 8),
879 ERASEINFO(0x10000, 127),
882 .mfr_id = MANUFACTURER_INTEL,
883 .dev_id = I28F640B3T,
884 .name = "Intel 28F640B3T",
886 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
888 .DevSize = SIZE_8MiB,
889 .CmdSet = P_ID_INTEL_STD,
892 ERASEINFO(0x10000, 127),
893 ERASEINFO(0x02000, 8),
896 .mfr_id = MANUFACTURER_INTEL,
898 .name = "Intel 82802AB",
900 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
902 .DevSize = SIZE_512KiB,
903 .CmdSet = P_ID_INTEL_EXT,
906 ERASEINFO(0x10000,8),
909 .mfr_id = MANUFACTURER_INTEL,
911 .name = "Intel 82802AC",
913 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
915 .DevSize = SIZE_1MiB,
916 .CmdSet = P_ID_INTEL_EXT,
919 ERASEINFO(0x10000,16),
922 .mfr_id = MANUFACTURER_MACRONIX,
923 .dev_id = MX29LV160T,
924 .name = "MXIC MX29LV160T",
926 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
927 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
929 .DevSize = SIZE_2MiB,
930 .CmdSet = P_ID_AMD_STD,
933 ERASEINFO(0x10000,31),
934 ERASEINFO(0x08000,1),
935 ERASEINFO(0x02000,2),
939 .mfr_id = MANUFACTURER_MACRONIX,
940 .dev_id = MX29LV160B,
941 .name = "MXIC MX29LV160B",
943 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
944 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
946 .DevSize = SIZE_2MiB,
947 .CmdSet = P_ID_AMD_STD,
950 ERASEINFO(0x04000,1),
951 ERASEINFO(0x02000,2),
952 ERASEINFO(0x08000,1),
953 ERASEINFO(0x10000,31)
956 .mfr_id = MANUFACTURER_MACRONIX,
958 .name = "Macronix MX29F016",
960 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
962 .DevSize = SIZE_2MiB,
963 .CmdSet = P_ID_AMD_STD,
966 ERASEINFO(0x10000,32),
969 .mfr_id = MANUFACTURER_MACRONIX,
971 .name = "Macronix MX29F004T",
973 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
975 .DevSize = SIZE_512KiB,
976 .CmdSet = P_ID_AMD_STD,
979 ERASEINFO(0x10000,7),
980 ERASEINFO(0x08000,1),
981 ERASEINFO(0x02000,2),
982 ERASEINFO(0x04000,1),
985 .mfr_id = MANUFACTURER_MACRONIX,
987 .name = "Macronix MX29F004B",
989 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
991 .DevSize = SIZE_512KiB,
992 .CmdSet = P_ID_AMD_STD,
995 ERASEINFO(0x04000,1),
996 ERASEINFO(0x02000,2),
997 ERASEINFO(0x08000,1),
998 ERASEINFO(0x10000,7),
1001 .mfr_id = MANUFACTURER_PMC,
1002 .dev_id = PM49FL002,
1003 .name = "PMC Pm49FL002",
1005 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1007 .DevSize = SIZE_256KiB,
1008 .CmdSet = P_ID_AMD_STD,
1009 .NumEraseRegions= 1,
1011 ERASEINFO( 0x01000, 64 )
1014 .mfr_id = MANUFACTURER_PMC,
1015 .dev_id = PM49FL004,
1016 .name = "PMC Pm49FL004",
1018 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1020 .DevSize = SIZE_512KiB,
1021 .CmdSet = P_ID_AMD_STD,
1022 .NumEraseRegions= 1,
1024 ERASEINFO( 0x01000, 128 )
1027 .mfr_id = MANUFACTURER_PMC,
1028 .dev_id = PM49FL008,
1029 .name = "PMC Pm49FL008",
1031 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1033 .DevSize = SIZE_1MiB,
1034 .CmdSet = P_ID_AMD_STD,
1035 .NumEraseRegions= 1,
1037 ERASEINFO( 0x01000, 256 )
1040 .mfr_id = MANUFACTURER_SST,
1041 .dev_id = SST39LF512,
1042 .name = "SST 39LF512",
1044 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1046 .DevSize = SIZE_64KiB,
1047 .CmdSet = P_ID_AMD_STD,
1048 .NumEraseRegions= 1,
1050 ERASEINFO(0x01000,16),
1053 .mfr_id = MANUFACTURER_SST,
1054 .dev_id = SST39LF010,
1055 .name = "SST 39LF010",
1057 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1059 .DevSize = SIZE_128KiB,
1060 .CmdSet = P_ID_AMD_STD,
1061 .NumEraseRegions= 1,
1063 ERASEINFO(0x01000,32),
1066 .mfr_id = MANUFACTURER_SST,
1067 .dev_id = SST39LF020,
1068 .name = "SST 39LF020",
1070 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1072 .DevSize = SIZE_256KiB,
1073 .CmdSet = P_ID_AMD_STD,
1074 .NumEraseRegions= 1,
1076 ERASEINFO(0x01000,64),
1079 .mfr_id = MANUFACTURER_SST,
1080 .dev_id = SST39LF040,
1081 .name = "SST 39LF040",
1083 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1085 .DevSize = SIZE_512KiB,
1086 .CmdSet = P_ID_AMD_STD,
1087 .NumEraseRegions= 1,
1089 ERASEINFO(0x01000,128),
1092 .mfr_id = MANUFACTURER_SST,
1093 .dev_id = SST39SF010A,
1094 .name = "SST 39SF010A",
1096 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1098 .DevSize = SIZE_128KiB,
1099 .CmdSet = P_ID_AMD_STD,
1100 .NumEraseRegions= 1,
1102 ERASEINFO(0x01000,32),
1105 .mfr_id = MANUFACTURER_SST,
1106 .dev_id = SST39SF020A,
1107 .name = "SST 39SF020A",
1109 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1111 .DevSize = SIZE_256KiB,
1112 .CmdSet = P_ID_AMD_STD,
1113 .NumEraseRegions= 1,
1115 ERASEINFO(0x01000,64),
1118 .mfr_id = MANUFACTURER_SST,
1119 .dev_id = SST49LF030A,
1120 .name = "SST 49LF030A",
1122 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1124 .DevSize = SIZE_512KiB,
1125 .CmdSet = P_ID_AMD_STD,
1126 .NumEraseRegions= 1,
1128 ERASEINFO(0x01000,96),
1131 .mfr_id = MANUFACTURER_SST,
1132 .dev_id = SST49LF040A,
1133 .name = "SST 49LF040A",
1135 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1137 .DevSize = SIZE_512KiB,
1138 .CmdSet = P_ID_AMD_STD,
1139 .NumEraseRegions= 1,
1141 ERASEINFO(0x01000,128),
1144 .mfr_id = MANUFACTURER_SST,
1145 .dev_id = SST49LF080A,
1146 .name = "SST 49LF080A",
1148 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1150 .DevSize = SIZE_1MiB,
1151 .CmdSet = P_ID_AMD_STD,
1152 .NumEraseRegions= 1,
1154 ERASEINFO(0x01000,256),
1157 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1158 .dev_id = M29W800DT,
1159 .name = "ST M29W800DT",
1161 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1162 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1164 .DevSize = SIZE_1MiB,
1165 .CmdSet = P_ID_AMD_STD,
1166 .NumEraseRegions= 4,
1168 ERASEINFO(0x10000,15),
1169 ERASEINFO(0x08000,1),
1170 ERASEINFO(0x02000,2),
1171 ERASEINFO(0x04000,1)
1174 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1175 .dev_id = M29W800DB,
1176 .name = "ST M29W800DB",
1178 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1179 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1181 .DevSize = SIZE_1MiB,
1182 .CmdSet = P_ID_AMD_STD,
1183 .NumEraseRegions= 4,
1185 ERASEINFO(0x04000,1),
1186 ERASEINFO(0x02000,2),
1187 ERASEINFO(0x08000,1),
1188 ERASEINFO(0x10000,15)
1191 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1192 .dev_id = M29W160DT,
1193 .name = "ST M29W160DT",
1195 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1196 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1198 .DevSize = SIZE_2MiB,
1199 .CmdSet = P_ID_AMD_STD,
1200 .NumEraseRegions= 4,
1202 ERASEINFO(0x10000,31),
1203 ERASEINFO(0x08000,1),
1204 ERASEINFO(0x02000,2),
1205 ERASEINFO(0x04000,1)
1208 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1209 .dev_id = M29W160DB,
1210 .name = "ST M29W160DB",
1212 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1213 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1215 .DevSize = SIZE_2MiB,
1216 .CmdSet = P_ID_AMD_STD,
1217 .NumEraseRegions= 4,
1219 ERASEINFO(0x04000,1),
1220 ERASEINFO(0x02000,2),
1221 ERASEINFO(0x08000,1),
1222 ERASEINFO(0x10000,31)
1225 .mfr_id = MANUFACTURER_ST,
1227 .name = "ST M29W040B",
1229 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1231 .DevSize = SIZE_512KiB,
1232 .CmdSet = P_ID_AMD_STD,
1233 .NumEraseRegions= 1,
1235 ERASEINFO(0x10000,8),
1238 .mfr_id = MANUFACTURER_TOSHIBA,
1239 .dev_id = TC58FVT160,
1240 .name = "Toshiba TC58FVT160",
1242 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1243 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1245 .DevSize = SIZE_2MiB,
1246 .CmdSet = P_ID_AMD_STD,
1247 .NumEraseRegions= 4,
1249 ERASEINFO(0x10000,31),
1250 ERASEINFO(0x08000,1),
1251 ERASEINFO(0x02000,2),
1252 ERASEINFO(0x04000,1)
1255 .mfr_id = MANUFACTURER_TOSHIBA,
1256 .dev_id = TC58FVB160,
1257 .name = "Toshiba TC58FVB160",
1259 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1260 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1262 .DevSize = SIZE_2MiB,
1263 .CmdSet = P_ID_AMD_STD,
1264 .NumEraseRegions= 4,
1266 ERASEINFO(0x04000,1),
1267 ERASEINFO(0x02000,2),
1268 ERASEINFO(0x08000,1),
1269 ERASEINFO(0x10000,31)
1272 .mfr_id = MANUFACTURER_TOSHIBA,
1273 .dev_id = TC58FVB321,
1274 .name = "Toshiba TC58FVB321",
1276 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1277 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1279 .DevSize = SIZE_4MiB,
1280 .CmdSet = P_ID_AMD_STD,
1281 .NumEraseRegions= 2,
1283 ERASEINFO(0x02000,8),
1284 ERASEINFO(0x10000,63)
1287 .mfr_id = MANUFACTURER_TOSHIBA,
1288 .dev_id = TC58FVT321,
1289 .name = "Toshiba TC58FVT321",
1291 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1292 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1294 .DevSize = SIZE_4MiB,
1295 .CmdSet = P_ID_AMD_STD,
1296 .NumEraseRegions= 2,
1298 ERASEINFO(0x10000,63),
1299 ERASEINFO(0x02000,8)
1302 .mfr_id = MANUFACTURER_TOSHIBA,
1303 .dev_id = TC58FVB641,
1304 .name = "Toshiba TC58FVB641",
1306 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1307 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1309 .DevSize = SIZE_8MiB,
1310 .CmdSet = P_ID_AMD_STD,
1311 .NumEraseRegions= 2,
1313 ERASEINFO(0x02000,8),
1314 ERASEINFO(0x10000,127)
1317 .mfr_id = MANUFACTURER_TOSHIBA,
1318 .dev_id = TC58FVT641,
1319 .name = "Toshiba TC58FVT641",
1321 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1322 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1324 .DevSize = SIZE_8MiB,
1325 .CmdSet = P_ID_AMD_STD,
1326 .NumEraseRegions= 2,
1328 ERASEINFO(0x10000,127),
1329 ERASEINFO(0x02000,8)
1332 .mfr_id = MANUFACTURER_WINBOND,
1334 .name = "Winbond W49V002A",
1336 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1338 .DevSize = SIZE_256KiB,
1339 .CmdSet = P_ID_AMD_STD,
1340 .NumEraseRegions= 4,
1342 ERASEINFO(0x10000, 3),
1343 ERASEINFO(0x08000, 1),
1344 ERASEINFO(0x02000, 2),
1345 ERASEINFO(0x04000, 1),
1351 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
1353 static int jedec_probe_chip(struct map_info *map, __u32 base,
1354 struct flchip *chips, struct cfi_private *cfi);
1356 struct mtd_info *jedec_probe(struct map_info *map);
1358 static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
1359 struct cfi_private *cfi)
1362 mask = (1 << (cfi->device_type * 8)) -1;
1363 result = cfi_read(map, base);
1368 static inline u32 jedec_read_id(struct map_info *map, __u32 base,
1369 struct cfi_private *cfi)
1373 osf = cfi->interleave *cfi->device_type;
1374 mask = (1 << (cfi->device_type * 8)) -1;
1375 result = cfi_read(map, base + osf);
1380 static inline void jedec_reset(u32 base, struct map_info *map,
1381 struct cfi_private *cfi)
1384 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
1385 /* Some misdesigned intel chips do not respond for 0xF0 for a reset,
1386 * so ensure we're in read mode. Send both the Intel and the AMD command
1387 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
1388 * this should be safe.
1390 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
1391 /* FIXME - should have reset delay before continuing */
1395 static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type)
1398 __u8 uaddr = MTD_UADDR_NOT_SUPPORTED;
1400 switch ( device_type ) {
1401 case CFI_DEVICETYPE_X8: uaddr_idx = 0; break;
1402 case CFI_DEVICETYPE_X16: uaddr_idx = 1; break;
1403 case CFI_DEVICETYPE_X32: uaddr_idx = 2; break;
1405 printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n",
1406 __func__, device_type);
1410 uaddr = finfo->uaddr[uaddr_idx];
1417 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1419 int i,num_erase_regions;
1422 printk("Found: %s\n",jedec_table[index].name);
1424 num_erase_regions = jedec_table[index].NumEraseRegions;
1426 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
1428 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
1432 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
1434 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
1435 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
1436 p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
1437 p_cfi->cfi_mode = CFI_MODE_JEDEC;
1439 for (i=0; i<num_erase_regions; i++){
1440 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
1442 p_cfi->cmdset_priv = 0;
1444 /* This may be redundant for some cases, but it doesn't hurt */
1445 p_cfi->mfr = jedec_table[index].mfr_id;
1446 p_cfi->id = jedec_table[index].dev_id;
1448 uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type);
1449 if ( MTD_UADDR_NOT_SUPPORTED ) {
1450 kfree( p_cfi->cfiq );
1453 p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1;
1454 p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2;
1461 * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing
1462 * the mapped address, unlock addresses, and proper chip ID. This function
1463 * attempts to minimize errors. It is doubtfull that this probe will ever
1464 * be perfect - consequently there should be some module parameters that
1465 * could be manually specified to force the chip info.
1467 static inline int jedec_match( __u32 base,
1468 struct map_info *map,
1469 struct cfi_private *cfi,
1470 const struct amd_flash_info *finfo )
1472 int rc = 0; /* failure until all tests pass */
1476 /* The ID's must match */
1477 if ( cfi->mfr != finfo->mfr_id || cfi->id != finfo->dev_id ) {
1481 /* the part size must fit in the memory window */
1482 DEBUG( MTD_DEBUG_LEVEL3,
1483 "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
1484 __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
1485 if ( base + ( 1 << finfo->DevSize ) > map->size ) {
1486 DEBUG( MTD_DEBUG_LEVEL3,
1487 "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
1488 __func__, finfo->mfr_id, finfo->dev_id,
1489 1 << finfo->DevSize );
1493 uaddr = finfo_uaddr(finfo, cfi->device_type);
1494 if ( MTD_UADDR_NOT_SUPPORTED ) {
1498 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
1499 __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
1500 if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
1501 && ( unlock_addrs[uaddr].addr1 != cfi->addr_unlock1
1502 || unlock_addrs[uaddr].addr2 != cfi->addr_unlock2 ) ) {
1503 DEBUG( MTD_DEBUG_LEVEL3,
1504 "MTD %s(): 0x%.4x 0x%.4x did not match\n",
1506 unlock_addrs[uaddr].addr1,
1507 unlock_addrs[uaddr].addr2 );
1512 * Make sure the ID's dissappear when the device is taken out of
1513 * ID mode. The only time this should fail when it should succeed
1514 * is when the ID's are written as data to the same
1515 * addresses. For this rare and unfortunate case the chip
1516 * cannot be probed correctly.
1517 * FIXME - write a driver that takes all of the chip info as
1518 * module parameters, doesn't probe but forces a load.
1520 DEBUG( MTD_DEBUG_LEVEL3,
1521 "MTD %s(): check ID's disappear when not in ID mode\n",
1523 jedec_reset( base, map, cfi );
1524 mfr = jedec_read_mfr( map, base, cfi );
1525 id = jedec_read_id( map, base, cfi );
1526 if ( mfr == cfi->mfr && id == cfi->id ) {
1527 DEBUG( MTD_DEBUG_LEVEL3,
1528 "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
1529 "You might need to manually specify JEDEC parameters.\n",
1530 __func__, cfi->mfr, cfi->id );
1534 /* all tests passed - mark as success */
1538 * Put the device back in ID mode - only need to do this if we
1539 * were truly frobbing a real device.
1541 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
1542 if(cfi->addr_unlock1) {
1543 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1544 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1546 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1547 /* FIXME - should have a delay before continuing */
1554 static int jedec_probe_chip(struct map_info *map, __u32 base,
1555 struct flchip *chips, struct cfi_private *cfi)
1561 * FIXME - eventually replace these unlock address seeds with
1562 * information from unlock_addrs[].
1564 if (!cfi->numchips) {
1565 switch (cfi->device_type) {
1566 case CFI_DEVICETYPE_X8:
1567 cfi->addr_unlock1 = 0x555;
1568 cfi->addr_unlock2 = 0x2aa;
1570 case CFI_DEVICETYPE_X16:
1571 cfi->addr_unlock1 = 0xaaa;
1572 if (map->buswidth == cfi->interleave) {
1573 /* X16 chip(s) in X8 mode */
1574 cfi->addr_unlock2 = 0x555;
1576 cfi->addr_unlock2 = 0x554;
1579 case CFI_DEVICETYPE_X32:
1580 cfi->addr_unlock1 = 0x1555;
1581 cfi->addr_unlock2 = 0xaaa;
1584 printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type);
1590 /* Make certain we aren't probing past the end of map */
1591 if (base >= map->size) {
1593 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
1594 base, map->size -1);
1598 if ((base + cfi->addr_unlock1) >= map->size) {
1600 "Probe at addr_unlock1(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n",
1601 base, cfi->addr_unlock1, map->size -1);
1605 if ((base + cfi->addr_unlock2) >= map->size) {
1607 "Probe at addr_unlock2(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n",
1608 base, cfi->addr_unlock2, map->size -1);
1614 jedec_reset(base, map, cfi);
1616 /* Autoselect Mode */
1617 if(cfi->addr_unlock1) {
1618 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1619 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1621 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1622 /* FIXME - should have a delay before continuing */
1624 if (!cfi->numchips) {
1625 /* This is the first time we're called. Set up the CFI
1626 stuff accordingly and return */
1628 cfi->mfr = jedec_read_mfr(map, base, cfi);
1629 cfi->id = jedec_read_id(map, base, cfi);
1630 printk(KERN_INFO "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
1631 cfi->mfr, cfi->id, cfi->interleave, cfi->device_type);
1632 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
1633 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
1634 DEBUG( MTD_DEBUG_LEVEL3,
1635 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
1636 __func__, cfi->mfr, cfi->id,
1637 cfi->addr_unlock1, cfi->addr_unlock2 );
1638 if (!cfi_jedec_setup(cfi, i))
1643 switch(unlockpass++) {
1645 cfi->addr_unlock1 |= cfi->addr_unlock1 << 4;
1646 cfi->addr_unlock2 |= cfi->addr_unlock2 << 4;
1649 cfi->addr_unlock1 = cfi->addr_unlock2 = 0;
1657 /* Make sure it is a chip of the same manufacturer and id */
1658 mfr = jedec_read_mfr(map, base, cfi);
1659 id = jedec_read_id(map, base, cfi);
1661 if ((mfr != cfi->mfr) || (id != cfi->id)) {
1662 printk(KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n",
1663 map->name, mfr, id, base);
1664 jedec_reset(base, map, cfi);
1669 /* Check each previous chip to see if it's an alias */
1670 for (i=0; i<cfi->numchips; i++) {
1671 /* This chip should be in read mode if it's one
1672 we've already touched. */
1673 if (jedec_read_mfr(map, chips[i].start, cfi) == cfi->mfr &&
1674 jedec_read_id(map, chips[i].start, cfi) == cfi->id) {
1675 /* Eep. This chip also looks like it's in autoselect mode.
1676 Is it an alias for the new one? */
1677 jedec_reset(chips[i].start, map, cfi);
1679 /* If the device IDs go away, it's an alias */
1680 if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
1681 jedec_read_id(map, base, cfi) != cfi->id) {
1682 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
1683 map->name, base, chips[i].start);
1687 /* Yes, it's actually got the device IDs as data. Most
1688 * unfortunate. Stick the new chip in read mode
1689 * too and if it's the same, assume it's an alias. */
1690 /* FIXME: Use other modes to do a proper check */
1691 jedec_reset(base, map, cfi);
1692 if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
1693 jedec_read_id(map, base, cfi) == cfi->id) {
1694 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
1695 map->name, base, chips[i].start);
1701 /* OK, if we got to here, then none of the previous chips appear to
1702 be aliases for the current one. */
1703 if (cfi->numchips == MAX_CFI_CHIPS) {
1704 printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
1705 /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
1708 chips[cfi->numchips].start = base;
1709 chips[cfi->numchips].state = FL_READY;
1713 /* Put it back into Read Mode */
1714 jedec_reset(base, map, cfi);
1716 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n",
1717 map->name, cfi->interleave, cfi->device_type*8, base,
1723 static struct chip_probe jedec_chip_probe = {
1725 .probe_chip = jedec_probe_chip
1728 struct mtd_info *jedec_probe(struct map_info *map)
1731 * Just use the generic probe stuff to call our CFI-specific
1732 * chip_probe routine in all the possible permutations, etc.
1734 return mtd_do_chip_probe(map, &jedec_chip_probe);
1737 static struct mtd_chip_driver jedec_chipdrv = {
1738 .probe = jedec_probe,
1739 .name = "jedec_probe",
1740 .module = THIS_MODULE
1743 int __init jedec_probe_init(void)
1745 register_mtd_chip_driver(&jedec_chipdrv);
1749 static void __exit jedec_probe_exit(void)
1751 unregister_mtd_chip_driver(&jedec_chipdrv);
1754 module_init(jedec_probe_init);
1755 module_exit(jedec_probe_exit);
1757 MODULE_LICENSE("GPL");
1758 MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
1759 MODULE_DESCRIPTION("Probe code for JEDEC-compliant flash chips");