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>
20 #include <linux/mtd/mtd.h>
21 #include <linux/mtd/map.h>
22 #include <linux/mtd/cfi.h>
23 #include <linux/mtd/gen_probe.h>
26 #define MANUFACTURER_AMD 0x0001
27 #define MANUFACTURER_ATMEL 0x001f
28 #define MANUFACTURER_FUJITSU 0x0004
29 #define MANUFACTURER_INTEL 0x0089
30 #define MANUFACTURER_MACRONIX 0x00C2
31 #define MANUFACTURER_PMC 0x009D
32 #define MANUFACTURER_SST 0x00BF
33 #define MANUFACTURER_ST 0x0020
34 #define MANUFACTURER_TOSHIBA 0x0098
35 #define MANUFACTURER_WINBOND 0x00da
39 #define AM29F800BB 0x2258
40 #define AM29F800BT 0x22D6
41 #define AM29LV800BB 0x225B
42 #define AM29LV800BT 0x22DA
43 #define AM29LV160DT 0x22C4
44 #define AM29LV160DB 0x2249
45 #define AM29F017D 0x003D
46 #define AM29F016D 0x00AD
47 #define AM29F080 0x00D5
48 #define AM29F040 0x00A4
49 #define AM29LV040B 0x004F
50 #define AM29F032B 0x0041
53 #define AT49BV512 0x0003
54 #define AT29LV512 0x003d
55 #define AT49BV16X 0x00C0
56 #define AT49BV16XT 0x00C2
57 #define AT49BV32X 0x00C8
58 #define AT49BV32XT 0x00C9
61 #define MBM29LV650UE 0x22D7
62 #define MBM29LV320TE 0x22F6
63 #define MBM29LV320BE 0x22F9
64 #define MBM29LV160TE 0x22C4
65 #define MBM29LV160BE 0x2249
66 #define MBM29LV800BA 0x225B
67 #define MBM29LV800TA 0x22DA
70 #define I28F004B3T 0x00d4
71 #define I28F004B3B 0x00d5
72 #define I28F400B3T 0x8894
73 #define I28F400B3B 0x8895
74 #define I28F008S5 0x00a6
75 #define I28F016S5 0x00a0
76 #define I28F008SA 0x00a2
77 #define I28F008B3T 0x00d2
78 #define I28F008B3B 0x00d3
79 #define I28F800B3T 0x8892
80 #define I28F800B3B 0x8893
81 #define I28F016S3 0x00aa
82 #define I28F016B3T 0x00d0
83 #define I28F016B3B 0x00d1
84 #define I28F160B3T 0x8890
85 #define I28F160B3B 0x8891
86 #define I28F320B3T 0x8896
87 #define I28F320B3B 0x8897
88 #define I28F640B3T 0x8898
89 #define I28F640B3B 0x8899
90 #define I82802AB 0x00ad
91 #define I82802AC 0x00ac
94 #define MX29LV160T 0x22C4
95 #define MX29LV160B 0x2249
96 #define MX29F016 0x00AD
97 #define MX29F004T 0x0045
98 #define MX29F004B 0x0046
101 #define PM49FL002 0x006D
102 #define PM49FL004 0x006E
103 #define PM49FL008 0x006A
105 /* ST - www.st.com */
106 #define M29W800DT 0x00D7
107 #define M29W800DB 0x005B
108 #define M29W160DT 0x22C4
109 #define M29W160DB 0x2249
110 #define M29W040B 0x00E3
113 #define SST29EE512 0x005d
114 #define SST29LE512 0x003d
115 #define SST39LF800 0x2781
116 #define SST39LF160 0x2782
117 #define SST39LF512 0x00D4
118 #define SST39LF010 0x00D5
119 #define SST39LF020 0x00D6
120 #define SST39LF040 0x00D7
121 #define SST39SF010A 0x00B5
122 #define SST39SF020A 0x00B6
123 #define SST49LF030A 0x001C
124 #define SST49LF040A 0x0051
125 #define SST49LF080A 0x005B
128 #define TC58FVT160 0x00C2
129 #define TC58FVB160 0x0043
130 #define TC58FVT321 0x009A
131 #define TC58FVB321 0x009C
132 #define TC58FVT641 0x0093
133 #define TC58FVB641 0x0095
136 #define W49V002A 0x00b0
140 * Unlock address sets for AMD command sets.
141 * Intel command sets use the MTD_UADDR_UNNECESSARY.
142 * Each identifier, except MTD_UADDR_UNNECESSARY, and
143 * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[].
144 * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure
145 * initialization need not require initializing all of the
146 * unlock addresses for all bit widths.
149 MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */
150 MTD_UADDR_0x0555_0x02AA,
151 MTD_UADDR_0x0555_0x0AAA,
152 MTD_UADDR_0x5555_0x2AAA,
153 MTD_UADDR_0x0AAA_0x0555,
154 MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */
155 MTD_UADDR_UNNECESSARY, /* Does not require any address */
166 * I don't like the fact that the first entry in unlock_addrs[]
167 * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
168 * should not be used. The problem is that structures with
169 * initializers have extra fields initialized to 0. It is _very_
170 * desireable to have the unlock address entries for unsupported
171 * data widths automatically initialized - that means that
172 * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
175 static const struct unlock_addr unlock_addrs[] = {
176 [MTD_UADDR_NOT_SUPPORTED] = {
181 [MTD_UADDR_0x0555_0x02AA] = {
186 [MTD_UADDR_0x0555_0x0AAA] = {
191 [MTD_UADDR_0x5555_0x2AAA] = {
196 [MTD_UADDR_0x0AAA_0x0555] = {
201 [MTD_UADDR_DONT_CARE] = {
202 .addr1 = 0x0000, /* Doesn't matter which address */
203 .addr2 = 0x0000 /* is used - must be last entry */
208 struct amd_flash_info {
213 const int InterfaceDesc;
214 const int NumEraseRegions;
216 const __u8 uaddr[3]; /* unlock addrs for 8, 16, 32 modes */
217 const ulong regions[4];
220 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
222 #define SIZE_64KiB 16
223 #define SIZE_128KiB 17
224 #define SIZE_256KiB 18
225 #define SIZE_512KiB 19
233 * Please keep this list ordered by manufacturer!
234 * Fortunately, the list isn't searched often and so a
235 * slow, linear search isn't so bad.
237 static const struct amd_flash_info jedec_table[] = {
239 .mfr_id = MANUFACTURER_AMD,
241 .name = "AMD AM29F032B",
243 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
245 .DevSize = SIZE_4MiB,
246 .CmdSet = P_ID_AMD_STD,
249 ERASEINFO(0x10000,64)
252 .mfr_id = MANUFACTURER_AMD,
253 .dev_id = AM29LV160DT,
254 .name = "AMD AM29LV160DT",
256 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
257 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
259 .DevSize = SIZE_2MiB,
260 .CmdSet = P_ID_AMD_STD,
263 ERASEINFO(0x10000,31),
264 ERASEINFO(0x08000,1),
265 ERASEINFO(0x02000,2),
269 .mfr_id = MANUFACTURER_AMD,
270 .dev_id = AM29LV160DB,
271 .name = "AMD AM29LV160DB",
273 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
274 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
276 .DevSize = SIZE_2MiB,
277 .CmdSet = P_ID_AMD_STD,
280 ERASEINFO(0x04000,1),
281 ERASEINFO(0x02000,2),
282 ERASEINFO(0x08000,1),
283 ERASEINFO(0x10000,31)
286 .mfr_id = MANUFACTURER_AMD,
287 .dev_id = AM29LV800BB,
288 .name = "AMD AM29LV800BB",
290 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
291 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
293 .DevSize = SIZE_1MiB,
294 .CmdSet = P_ID_AMD_STD,
297 ERASEINFO(0x04000,1),
298 ERASEINFO(0x02000,2),
299 ERASEINFO(0x08000,1),
300 ERASEINFO(0x10000,15),
303 .mfr_id = MANUFACTURER_AMD,
304 .dev_id = AM29F800BB,
305 .name = "AMD AM29F800BB",
307 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
308 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
310 .DevSize = SIZE_1MiB,
311 .CmdSet = P_ID_AMD_STD,
314 ERASEINFO(0x04000,1),
315 ERASEINFO(0x02000,2),
316 ERASEINFO(0x08000,1),
317 ERASEINFO(0x10000,15),
320 .mfr_id = MANUFACTURER_AMD,
321 .dev_id = AM29LV800BT,
322 .name = "AMD AM29LV800BT",
324 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
325 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
327 .DevSize = SIZE_1MiB,
328 .CmdSet = P_ID_AMD_STD,
331 ERASEINFO(0x10000,15),
332 ERASEINFO(0x08000,1),
333 ERASEINFO(0x02000,2),
337 .mfr_id = MANUFACTURER_AMD,
338 .dev_id = AM29F800BT,
339 .name = "AMD AM29F800BT",
341 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
342 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
344 .DevSize = SIZE_1MiB,
345 .CmdSet = P_ID_AMD_STD,
348 ERASEINFO(0x10000,15),
349 ERASEINFO(0x08000,1),
350 ERASEINFO(0x02000,2),
354 .mfr_id = MANUFACTURER_AMD,
356 .name = "AMD AM29F017D",
358 [0] = MTD_UADDR_DONT_CARE /* x8 */
360 .DevSize = SIZE_2MiB,
361 .CmdSet = P_ID_AMD_STD,
364 ERASEINFO(0x10000,32),
367 .mfr_id = MANUFACTURER_AMD,
369 .name = "AMD AM29F016D",
371 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
373 .DevSize = SIZE_2MiB,
374 .CmdSet = P_ID_AMD_STD,
377 ERASEINFO(0x10000,32),
380 .mfr_id = MANUFACTURER_AMD,
382 .name = "AMD AM29F080",
384 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
386 .DevSize = SIZE_1MiB,
387 .CmdSet = P_ID_AMD_STD,
390 ERASEINFO(0x10000,16),
393 .mfr_id = MANUFACTURER_AMD,
395 .name = "AMD AM29F040",
397 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
399 .DevSize = SIZE_512KiB,
400 .CmdSet = P_ID_AMD_STD,
403 ERASEINFO(0x10000,8),
406 .mfr_id = MANUFACTURER_AMD,
407 .dev_id = AM29LV040B,
408 .name = "AMD AM29LV040B",
410 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
412 .DevSize = SIZE_512KiB,
413 .CmdSet = P_ID_AMD_STD,
416 ERASEINFO(0x10000,8),
419 .mfr_id = MANUFACTURER_ATMEL,
421 .name = "Atmel AT49BV512",
423 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
425 .DevSize = SIZE_64KiB,
426 .CmdSet = P_ID_AMD_STD,
432 .mfr_id = MANUFACTURER_ATMEL,
434 .name = "Atmel AT29LV512",
436 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
438 .DevSize = SIZE_64KiB,
439 .CmdSet = P_ID_AMD_STD,
446 .mfr_id = MANUFACTURER_ATMEL,
448 .name = "Atmel AT49BV16X",
450 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
451 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
453 .DevSize = SIZE_2MiB,
454 .CmdSet = P_ID_AMD_STD,
457 ERASEINFO(0x02000,8),
458 ERASEINFO(0x10000,31)
461 .mfr_id = MANUFACTURER_ATMEL,
462 .dev_id = AT49BV16XT,
463 .name = "Atmel AT49BV16XT",
465 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
466 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
468 .DevSize = SIZE_2MiB,
469 .CmdSet = P_ID_AMD_STD,
472 ERASEINFO(0x10000,31),
476 .mfr_id = MANUFACTURER_ATMEL,
478 .name = "Atmel AT49BV32X",
480 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
481 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
483 .DevSize = SIZE_4MiB,
484 .CmdSet = P_ID_AMD_STD,
487 ERASEINFO(0x02000,8),
488 ERASEINFO(0x10000,63)
491 .mfr_id = MANUFACTURER_ATMEL,
492 .dev_id = AT49BV32XT,
493 .name = "Atmel AT49BV32XT",
495 [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
496 [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
498 .DevSize = SIZE_4MiB,
499 .CmdSet = P_ID_AMD_STD,
502 ERASEINFO(0x10000,63),
506 .mfr_id = MANUFACTURER_FUJITSU,
507 .dev_id = MBM29LV650UE,
508 .name = "Fujitsu MBM29LV650UE",
510 [0] = MTD_UADDR_DONT_CARE /* x16 */
512 .DevSize = SIZE_8MiB,
513 .CmdSet = P_ID_AMD_STD,
516 ERASEINFO(0x10000,128)
519 .mfr_id = MANUFACTURER_FUJITSU,
520 .dev_id = MBM29LV320TE,
521 .name = "Fujitsu MBM29LV320TE",
523 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
524 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
526 .DevSize = SIZE_4MiB,
527 .CmdSet = P_ID_AMD_STD,
530 ERASEINFO(0x10000,63),
534 .mfr_id = MANUFACTURER_FUJITSU,
535 .dev_id = MBM29LV320BE,
536 .name = "Fujitsu MBM29LV320BE",
538 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
539 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
541 .DevSize = SIZE_4MiB,
542 .CmdSet = P_ID_AMD_STD,
545 ERASEINFO(0x02000,8),
546 ERASEINFO(0x10000,63)
549 .mfr_id = MANUFACTURER_FUJITSU,
550 .dev_id = MBM29LV160TE,
551 .name = "Fujitsu MBM29LV160TE",
553 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
554 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
556 .DevSize = SIZE_2MiB,
557 .CmdSet = P_ID_AMD_STD,
560 ERASEINFO(0x10000,31),
561 ERASEINFO(0x08000,1),
562 ERASEINFO(0x02000,2),
566 .mfr_id = MANUFACTURER_FUJITSU,
567 .dev_id = MBM29LV160BE,
568 .name = "Fujitsu MBM29LV160BE",
570 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
571 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
573 .DevSize = SIZE_2MiB,
574 .CmdSet = P_ID_AMD_STD,
577 ERASEINFO(0x04000,1),
578 ERASEINFO(0x02000,2),
579 ERASEINFO(0x08000,1),
580 ERASEINFO(0x10000,31)
583 .mfr_id = MANUFACTURER_FUJITSU,
584 .dev_id = MBM29LV800BA,
585 .name = "Fujitsu MBM29LV800BA",
587 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
588 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
590 .DevSize = SIZE_1MiB,
591 .CmdSet = P_ID_AMD_STD,
594 ERASEINFO(0x04000,1),
595 ERASEINFO(0x02000,2),
596 ERASEINFO(0x08000,1),
597 ERASEINFO(0x10000,15)
600 .mfr_id = MANUFACTURER_FUJITSU,
601 .dev_id = MBM29LV800TA,
602 .name = "Fujitsu MBM29LV800TA",
604 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
605 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
607 .DevSize = SIZE_1MiB,
608 .CmdSet = P_ID_AMD_STD,
611 ERASEINFO(0x10000,15),
612 ERASEINFO(0x08000,1),
613 ERASEINFO(0x02000,2),
617 .mfr_id = MANUFACTURER_INTEL,
618 .dev_id = I28F004B3B,
619 .name = "Intel 28F004B3B",
621 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
623 .DevSize = SIZE_512KiB,
624 .CmdSet = P_ID_INTEL_STD,
627 ERASEINFO(0x02000, 8),
628 ERASEINFO(0x10000, 7),
631 .mfr_id = MANUFACTURER_INTEL,
632 .dev_id = I28F004B3T,
633 .name = "Intel 28F004B3T",
635 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
637 .DevSize = SIZE_512KiB,
638 .CmdSet = P_ID_INTEL_STD,
641 ERASEINFO(0x10000, 7),
642 ERASEINFO(0x02000, 8),
645 .mfr_id = MANUFACTURER_INTEL,
646 .dev_id = I28F400B3B,
647 .name = "Intel 28F400B3B",
649 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
650 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
652 .DevSize = SIZE_512KiB,
653 .CmdSet = P_ID_INTEL_STD,
656 ERASEINFO(0x02000, 8),
657 ERASEINFO(0x10000, 7),
660 .mfr_id = MANUFACTURER_INTEL,
661 .dev_id = I28F400B3T,
662 .name = "Intel 28F400B3T",
664 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
665 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
667 .DevSize = SIZE_512KiB,
668 .CmdSet = P_ID_INTEL_STD,
671 ERASEINFO(0x10000, 7),
672 ERASEINFO(0x02000, 8),
675 .mfr_id = MANUFACTURER_INTEL,
676 .dev_id = I28F008B3B,
677 .name = "Intel 28F008B3B",
679 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
681 .DevSize = SIZE_1MiB,
682 .CmdSet = P_ID_INTEL_STD,
685 ERASEINFO(0x02000, 8),
686 ERASEINFO(0x10000, 15),
689 .mfr_id = MANUFACTURER_INTEL,
690 .dev_id = I28F008B3T,
691 .name = "Intel 28F008B3T",
693 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
695 .DevSize = SIZE_1MiB,
696 .CmdSet = P_ID_INTEL_STD,
699 ERASEINFO(0x10000, 15),
700 ERASEINFO(0x02000, 8),
703 .mfr_id = MANUFACTURER_INTEL,
705 .name = "Intel 28F008S5",
707 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
709 .DevSize = SIZE_1MiB,
710 .CmdSet = P_ID_INTEL_EXT,
713 ERASEINFO(0x10000,16),
716 .mfr_id = MANUFACTURER_INTEL,
718 .name = "Intel 28F016S5",
720 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
722 .DevSize = SIZE_2MiB,
723 .CmdSet = P_ID_INTEL_EXT,
726 ERASEINFO(0x10000,32),
729 .mfr_id = MANUFACTURER_INTEL,
731 .name = "Intel 28F008SA",
733 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
735 .DevSize = SIZE_1MiB,
736 .CmdSet = P_ID_INTEL_STD,
739 ERASEINFO(0x10000, 16),
742 .mfr_id = MANUFACTURER_INTEL,
743 .dev_id = I28F800B3B,
744 .name = "Intel 28F800B3B",
746 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
748 .DevSize = SIZE_1MiB,
749 .CmdSet = P_ID_INTEL_STD,
752 ERASEINFO(0x02000, 8),
753 ERASEINFO(0x10000, 15),
756 .mfr_id = MANUFACTURER_INTEL,
757 .dev_id = I28F800B3T,
758 .name = "Intel 28F800B3T",
760 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
762 .DevSize = SIZE_1MiB,
763 .CmdSet = P_ID_INTEL_STD,
766 ERASEINFO(0x10000, 15),
767 ERASEINFO(0x02000, 8),
770 .mfr_id = MANUFACTURER_INTEL,
771 .dev_id = I28F016B3B,
772 .name = "Intel 28F016B3B",
774 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
776 .DevSize = SIZE_2MiB,
777 .CmdSet = P_ID_INTEL_STD,
780 ERASEINFO(0x02000, 8),
781 ERASEINFO(0x10000, 31),
784 .mfr_id = MANUFACTURER_INTEL,
786 .name = "Intel I28F016S3",
788 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
790 .DevSize = SIZE_2MiB,
791 .CmdSet = P_ID_INTEL_STD,
794 ERASEINFO(0x10000, 32),
797 .mfr_id = MANUFACTURER_INTEL,
798 .dev_id = I28F016B3T,
799 .name = "Intel 28F016B3T",
801 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
803 .DevSize = SIZE_2MiB,
804 .CmdSet = P_ID_INTEL_STD,
807 ERASEINFO(0x10000, 31),
808 ERASEINFO(0x02000, 8),
811 .mfr_id = MANUFACTURER_INTEL,
812 .dev_id = I28F160B3B,
813 .name = "Intel 28F160B3B",
815 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
817 .DevSize = SIZE_2MiB,
818 .CmdSet = P_ID_INTEL_STD,
821 ERASEINFO(0x02000, 8),
822 ERASEINFO(0x10000, 31),
825 .mfr_id = MANUFACTURER_INTEL,
826 .dev_id = I28F160B3T,
827 .name = "Intel 28F160B3T",
829 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
831 .DevSize = SIZE_2MiB,
832 .CmdSet = P_ID_INTEL_STD,
835 ERASEINFO(0x10000, 31),
836 ERASEINFO(0x02000, 8),
839 .mfr_id = MANUFACTURER_INTEL,
840 .dev_id = I28F320B3B,
841 .name = "Intel 28F320B3B",
843 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
845 .DevSize = SIZE_4MiB,
846 .CmdSet = P_ID_INTEL_STD,
849 ERASEINFO(0x02000, 8),
850 ERASEINFO(0x10000, 63),
853 .mfr_id = MANUFACTURER_INTEL,
854 .dev_id = I28F320B3T,
855 .name = "Intel 28F320B3T",
857 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
859 .DevSize = SIZE_4MiB,
860 .CmdSet = P_ID_INTEL_STD,
863 ERASEINFO(0x10000, 63),
864 ERASEINFO(0x02000, 8),
867 .mfr_id = MANUFACTURER_INTEL,
868 .dev_id = I28F640B3B,
869 .name = "Intel 28F640B3B",
871 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
873 .DevSize = SIZE_8MiB,
874 .CmdSet = P_ID_INTEL_STD,
877 ERASEINFO(0x02000, 8),
878 ERASEINFO(0x10000, 127),
881 .mfr_id = MANUFACTURER_INTEL,
882 .dev_id = I28F640B3T,
883 .name = "Intel 28F640B3T",
885 [1] = MTD_UADDR_UNNECESSARY, /* x16 */
887 .DevSize = SIZE_8MiB,
888 .CmdSet = P_ID_INTEL_STD,
891 ERASEINFO(0x10000, 127),
892 ERASEINFO(0x02000, 8),
895 .mfr_id = MANUFACTURER_INTEL,
897 .name = "Intel 82802AB",
899 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
901 .DevSize = SIZE_512KiB,
902 .CmdSet = P_ID_INTEL_EXT,
905 ERASEINFO(0x10000,8),
908 .mfr_id = MANUFACTURER_INTEL,
910 .name = "Intel 82802AC",
912 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
914 .DevSize = SIZE_1MiB,
915 .CmdSet = P_ID_INTEL_EXT,
918 ERASEINFO(0x10000,16),
921 .mfr_id = MANUFACTURER_MACRONIX,
922 .dev_id = MX29LV160T,
923 .name = "MXIC MX29LV160T",
925 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
926 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
928 .DevSize = SIZE_2MiB,
929 .CmdSet = P_ID_AMD_STD,
932 ERASEINFO(0x10000,31),
933 ERASEINFO(0x08000,1),
934 ERASEINFO(0x02000,2),
938 .mfr_id = MANUFACTURER_MACRONIX,
939 .dev_id = MX29LV160B,
940 .name = "MXIC MX29LV160B",
942 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
943 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
945 .DevSize = SIZE_2MiB,
946 .CmdSet = P_ID_AMD_STD,
949 ERASEINFO(0x04000,1),
950 ERASEINFO(0x02000,2),
951 ERASEINFO(0x08000,1),
952 ERASEINFO(0x10000,31)
955 .mfr_id = MANUFACTURER_MACRONIX,
957 .name = "Macronix MX29F016",
959 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
961 .DevSize = SIZE_2MiB,
962 .CmdSet = P_ID_AMD_STD,
965 ERASEINFO(0x10000,32),
968 .mfr_id = MANUFACTURER_MACRONIX,
970 .name = "Macronix MX29F004T",
972 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
974 .DevSize = SIZE_512KiB,
975 .CmdSet = P_ID_AMD_STD,
978 ERASEINFO(0x10000,7),
979 ERASEINFO(0x08000,1),
980 ERASEINFO(0x02000,2),
981 ERASEINFO(0x04000,1),
984 .mfr_id = MANUFACTURER_MACRONIX,
986 .name = "Macronix MX29F004B",
988 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
990 .DevSize = SIZE_512KiB,
991 .CmdSet = P_ID_AMD_STD,
994 ERASEINFO(0x04000,1),
995 ERASEINFO(0x02000,2),
996 ERASEINFO(0x08000,1),
997 ERASEINFO(0x10000,7),
1000 .mfr_id = MANUFACTURER_PMC,
1001 .dev_id = PM49FL002,
1002 .name = "PMC Pm49FL002",
1004 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1006 .DevSize = SIZE_256KiB,
1007 .CmdSet = P_ID_AMD_STD,
1008 .NumEraseRegions= 1,
1010 ERASEINFO( 0x01000, 64 )
1013 .mfr_id = MANUFACTURER_PMC,
1014 .dev_id = PM49FL004,
1015 .name = "PMC Pm49FL004",
1017 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1019 .DevSize = SIZE_512KiB,
1020 .CmdSet = P_ID_AMD_STD,
1021 .NumEraseRegions= 1,
1023 ERASEINFO( 0x01000, 128 )
1026 .mfr_id = MANUFACTURER_PMC,
1027 .dev_id = PM49FL008,
1028 .name = "PMC Pm49FL008",
1030 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1032 .DevSize = SIZE_1MiB,
1033 .CmdSet = P_ID_AMD_STD,
1034 .NumEraseRegions= 1,
1036 ERASEINFO( 0x01000, 256 )
1039 .mfr_id = MANUFACTURER_SST,
1040 .dev_id = SST39LF512,
1041 .name = "SST 39LF512",
1043 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1045 .DevSize = SIZE_64KiB,
1046 .CmdSet = P_ID_AMD_STD,
1047 .NumEraseRegions= 1,
1049 ERASEINFO(0x01000,16),
1052 .mfr_id = MANUFACTURER_SST,
1053 .dev_id = SST39LF010,
1054 .name = "SST 39LF010",
1056 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1058 .DevSize = SIZE_128KiB,
1059 .CmdSet = P_ID_AMD_STD,
1060 .NumEraseRegions= 1,
1062 ERASEINFO(0x01000,32),
1065 .mfr_id = MANUFACTURER_SST,
1066 .dev_id = SST39LF020,
1067 .name = "SST 39LF020",
1069 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1071 .DevSize = SIZE_256KiB,
1072 .CmdSet = P_ID_AMD_STD,
1073 .NumEraseRegions= 1,
1075 ERASEINFO(0x01000,64),
1078 .mfr_id = MANUFACTURER_SST,
1079 .dev_id = SST39LF040,
1080 .name = "SST 39LF040",
1082 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1084 .DevSize = SIZE_512KiB,
1085 .CmdSet = P_ID_AMD_STD,
1086 .NumEraseRegions= 1,
1088 ERASEINFO(0x01000,128),
1091 .mfr_id = MANUFACTURER_SST,
1092 .dev_id = SST39SF010A,
1093 .name = "SST 39SF010A",
1095 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1097 .DevSize = SIZE_128KiB,
1098 .CmdSet = P_ID_AMD_STD,
1099 .NumEraseRegions= 1,
1101 ERASEINFO(0x01000,32),
1104 .mfr_id = MANUFACTURER_SST,
1105 .dev_id = SST39SF020A,
1106 .name = "SST 39SF020A",
1108 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1110 .DevSize = SIZE_256KiB,
1111 .CmdSet = P_ID_AMD_STD,
1112 .NumEraseRegions= 1,
1114 ERASEINFO(0x01000,64),
1117 .mfr_id = MANUFACTURER_SST,
1118 .dev_id = SST49LF030A,
1119 .name = "SST 49LF030A",
1121 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1123 .DevSize = SIZE_512KiB,
1124 .CmdSet = P_ID_AMD_STD,
1125 .NumEraseRegions= 1,
1127 ERASEINFO(0x01000,96),
1130 .mfr_id = MANUFACTURER_SST,
1131 .dev_id = SST49LF040A,
1132 .name = "SST 49LF040A",
1134 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1136 .DevSize = SIZE_512KiB,
1137 .CmdSet = P_ID_AMD_STD,
1138 .NumEraseRegions= 1,
1140 ERASEINFO(0x01000,128),
1143 .mfr_id = MANUFACTURER_SST,
1144 .dev_id = SST49LF080A,
1145 .name = "SST 49LF080A",
1147 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1149 .DevSize = SIZE_1MiB,
1150 .CmdSet = P_ID_AMD_STD,
1151 .NumEraseRegions= 1,
1153 ERASEINFO(0x01000,256),
1156 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1157 .dev_id = M29W800DT,
1158 .name = "ST M29W800DT",
1160 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1161 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1163 .DevSize = SIZE_1MiB,
1164 .CmdSet = P_ID_AMD_STD,
1165 .NumEraseRegions= 4,
1167 ERASEINFO(0x10000,15),
1168 ERASEINFO(0x08000,1),
1169 ERASEINFO(0x02000,2),
1170 ERASEINFO(0x04000,1)
1173 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1174 .dev_id = M29W800DB,
1175 .name = "ST M29W800DB",
1177 [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
1178 [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
1180 .DevSize = SIZE_1MiB,
1181 .CmdSet = P_ID_AMD_STD,
1182 .NumEraseRegions= 4,
1184 ERASEINFO(0x04000,1),
1185 ERASEINFO(0x02000,2),
1186 ERASEINFO(0x08000,1),
1187 ERASEINFO(0x10000,15)
1190 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1191 .dev_id = M29W160DT,
1192 .name = "ST M29W160DT",
1194 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1195 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1197 .DevSize = SIZE_2MiB,
1198 .CmdSet = P_ID_AMD_STD,
1199 .NumEraseRegions= 4,
1201 ERASEINFO(0x10000,31),
1202 ERASEINFO(0x08000,1),
1203 ERASEINFO(0x02000,2),
1204 ERASEINFO(0x04000,1)
1207 .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
1208 .dev_id = M29W160DB,
1209 .name = "ST M29W160DB",
1211 [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
1212 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1214 .DevSize = SIZE_2MiB,
1215 .CmdSet = P_ID_AMD_STD,
1216 .NumEraseRegions= 4,
1218 ERASEINFO(0x04000,1),
1219 ERASEINFO(0x02000,2),
1220 ERASEINFO(0x08000,1),
1221 ERASEINFO(0x10000,31)
1224 .mfr_id = MANUFACTURER_ST,
1226 .name = "ST M29W040B",
1228 [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
1230 .DevSize = SIZE_512KiB,
1231 .CmdSet = P_ID_AMD_STD,
1232 .NumEraseRegions= 1,
1234 ERASEINFO(0x10000,8),
1237 .mfr_id = MANUFACTURER_TOSHIBA,
1238 .dev_id = TC58FVT160,
1239 .name = "Toshiba TC58FVT160",
1241 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1242 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1244 .DevSize = SIZE_2MiB,
1245 .CmdSet = P_ID_AMD_STD,
1246 .NumEraseRegions= 4,
1248 ERASEINFO(0x10000,31),
1249 ERASEINFO(0x08000,1),
1250 ERASEINFO(0x02000,2),
1251 ERASEINFO(0x04000,1)
1254 .mfr_id = MANUFACTURER_TOSHIBA,
1255 .dev_id = TC58FVB160,
1256 .name = "Toshiba TC58FVB160",
1258 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1259 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1261 .DevSize = SIZE_2MiB,
1262 .CmdSet = P_ID_AMD_STD,
1263 .NumEraseRegions= 4,
1265 ERASEINFO(0x04000,1),
1266 ERASEINFO(0x02000,2),
1267 ERASEINFO(0x08000,1),
1268 ERASEINFO(0x10000,31)
1271 .mfr_id = MANUFACTURER_TOSHIBA,
1272 .dev_id = TC58FVB321,
1273 .name = "Toshiba TC58FVB321",
1275 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1276 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1278 .DevSize = SIZE_4MiB,
1279 .CmdSet = P_ID_AMD_STD,
1280 .NumEraseRegions= 2,
1282 ERASEINFO(0x02000,8),
1283 ERASEINFO(0x10000,63)
1286 .mfr_id = MANUFACTURER_TOSHIBA,
1287 .dev_id = TC58FVT321,
1288 .name = "Toshiba TC58FVT321",
1290 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1291 [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
1293 .DevSize = SIZE_4MiB,
1294 .CmdSet = P_ID_AMD_STD,
1295 .NumEraseRegions= 2,
1297 ERASEINFO(0x10000,63),
1298 ERASEINFO(0x02000,8)
1301 .mfr_id = MANUFACTURER_TOSHIBA,
1302 .dev_id = TC58FVB641,
1303 .name = "Toshiba TC58FVB641",
1305 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1306 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1308 .DevSize = SIZE_8MiB,
1309 .CmdSet = P_ID_AMD_STD,
1310 .NumEraseRegions= 2,
1312 ERASEINFO(0x02000,8),
1313 ERASEINFO(0x10000,127)
1316 .mfr_id = MANUFACTURER_TOSHIBA,
1317 .dev_id = TC58FVT641,
1318 .name = "Toshiba TC58FVT641",
1320 [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
1321 [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
1323 .DevSize = SIZE_8MiB,
1324 .CmdSet = P_ID_AMD_STD,
1325 .NumEraseRegions= 2,
1327 ERASEINFO(0x10000,127),
1328 ERASEINFO(0x02000,8)
1331 .mfr_id = MANUFACTURER_WINBOND,
1333 .name = "Winbond W49V002A",
1335 [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
1337 .DevSize = SIZE_256KiB,
1338 .CmdSet = P_ID_AMD_STD,
1339 .NumEraseRegions= 4,
1341 ERASEINFO(0x10000, 3),
1342 ERASEINFO(0x08000, 1),
1343 ERASEINFO(0x02000, 2),
1344 ERASEINFO(0x04000, 1),
1350 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
1352 static int jedec_probe_chip(struct map_info *map, __u32 base,
1353 struct flchip *chips, struct cfi_private *cfi);
1355 struct mtd_info *jedec_probe(struct map_info *map);
1357 static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
1358 struct cfi_private *cfi)
1361 mask = (1 << (cfi->device_type * 8)) -1;
1362 result = cfi_read(map, base);
1367 static inline u32 jedec_read_id(struct map_info *map, __u32 base,
1368 struct cfi_private *cfi)
1372 osf = cfi->interleave *cfi->device_type;
1373 mask = (1 << (cfi->device_type * 8)) -1;
1374 result = cfi_read(map, base + osf);
1379 static inline void jedec_reset(u32 base, struct map_info *map,
1380 struct cfi_private *cfi)
1383 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
1384 /* Some misdesigned intel chips do not respond for 0xF0 for a reset,
1385 * so ensure we're in read mode. Send both the Intel and the AMD command
1386 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
1387 * this should be safe.
1389 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
1390 /* FIXME - should have reset delay before continuing */
1394 static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type)
1397 __u8 uaddr = MTD_UADDR_NOT_SUPPORTED;
1399 switch ( device_type ) {
1400 case CFI_DEVICETYPE_X8: uaddr_idx = 0; break;
1401 case CFI_DEVICETYPE_X16: uaddr_idx = 1; break;
1402 case CFI_DEVICETYPE_X32: uaddr_idx = 2; break;
1404 printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n",
1405 __func__, device_type);
1409 uaddr = finfo->uaddr[uaddr_idx];
1416 static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1418 int i,num_erase_regions;
1421 printk("Found: %s\n",jedec_table[index].name);
1423 num_erase_regions = jedec_table[index].NumEraseRegions;
1425 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
1427 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
1431 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
1433 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
1434 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
1435 p_cfi->cfiq->DevSize = jedec_table[index].DevSize;
1436 p_cfi->cfi_mode = CFI_MODE_JEDEC;
1438 for (i=0; i<num_erase_regions; i++){
1439 p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
1441 p_cfi->cmdset_priv = 0;
1443 /* This may be redundant for some cases, but it doesn't hurt */
1444 p_cfi->mfr = jedec_table[index].mfr_id;
1445 p_cfi->id = jedec_table[index].dev_id;
1447 uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type);
1448 if ( MTD_UADDR_NOT_SUPPORTED ) {
1449 kfree( p_cfi->cfiq );
1452 p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1;
1453 p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2;
1460 * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing
1461 * the mapped address, unlock addresses, and proper chip ID. This function
1462 * attempts to minimize errors. It is doubtfull that this probe will ever
1463 * be perfect - consequently there should be some module parameters that
1464 * could be manually specified to force the chip info.
1466 static inline int jedec_match( __u32 base,
1467 struct map_info *map,
1468 struct cfi_private *cfi,
1469 const struct amd_flash_info *finfo )
1471 int rc = 0; /* failure until all tests pass */
1475 /* The ID's must match */
1476 if ( cfi->mfr != finfo->mfr_id || cfi->id != finfo->dev_id ) {
1480 /* the part size must fit in the memory window */
1481 DEBUG( MTD_DEBUG_LEVEL3,
1482 "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
1483 __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
1484 if ( base + ( 1 << finfo->DevSize ) > map->size ) {
1485 DEBUG( MTD_DEBUG_LEVEL3,
1486 "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
1487 __func__, finfo->mfr_id, finfo->dev_id,
1488 1 << finfo->DevSize );
1492 uaddr = finfo_uaddr(finfo, cfi->device_type);
1493 if ( MTD_UADDR_NOT_SUPPORTED ) {
1497 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
1498 __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
1499 if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
1500 && ( unlock_addrs[uaddr].addr1 != cfi->addr_unlock1
1501 || unlock_addrs[uaddr].addr2 != cfi->addr_unlock2 ) ) {
1502 DEBUG( MTD_DEBUG_LEVEL3,
1503 "MTD %s(): 0x%.4x 0x%.4x did not match\n",
1505 unlock_addrs[uaddr].addr1,
1506 unlock_addrs[uaddr].addr2 );
1511 * Make sure the ID's dissappear when the device is taken out of
1512 * ID mode. The only time this should fail when it should succeed
1513 * is when the ID's are written as data to the same
1514 * addresses. For this rare and unfortunate case the chip
1515 * cannot be probed correctly.
1516 * FIXME - write a driver that takes all of the chip info as
1517 * module parameters, doesn't probe but forces a load.
1519 DEBUG( MTD_DEBUG_LEVEL3,
1520 "MTD %s(): check ID's disappear when not in ID mode\n",
1522 jedec_reset( base, map, cfi );
1523 mfr = jedec_read_mfr( map, base, cfi );
1524 id = jedec_read_id( map, base, cfi );
1525 if ( mfr == cfi->mfr && id == cfi->id ) {
1526 DEBUG( MTD_DEBUG_LEVEL3,
1527 "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
1528 "You might need to manually specify JEDEC parameters.\n",
1529 __func__, cfi->mfr, cfi->id );
1533 /* all tests passed - mark as success */
1537 * Put the device back in ID mode - only need to do this if we
1538 * were truly frobbing a real device.
1540 DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
1541 if(cfi->addr_unlock1) {
1542 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1543 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1545 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1546 /* FIXME - should have a delay before continuing */
1553 static int jedec_probe_chip(struct map_info *map, __u32 base,
1554 struct flchip *chips, struct cfi_private *cfi)
1560 * FIXME - eventually replace these unlock address seeds with
1561 * information from unlock_addrs[].
1563 if (!cfi->numchips) {
1564 switch (cfi->device_type) {
1565 case CFI_DEVICETYPE_X8:
1566 cfi->addr_unlock1 = 0x555;
1567 cfi->addr_unlock2 = 0x2aa;
1569 case CFI_DEVICETYPE_X16:
1570 cfi->addr_unlock1 = 0xaaa;
1571 if (map->buswidth == cfi->interleave) {
1572 /* X16 chip(s) in X8 mode */
1573 cfi->addr_unlock2 = 0x555;
1575 cfi->addr_unlock2 = 0x554;
1578 case CFI_DEVICETYPE_X32:
1579 cfi->addr_unlock1 = 0x1555;
1580 cfi->addr_unlock2 = 0xaaa;
1583 printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type);
1589 /* Make certain we aren't probing past the end of map */
1590 if (base >= map->size) {
1592 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
1593 base, map->size -1);
1597 if ((base + cfi->addr_unlock1) >= map->size) {
1599 "Probe at addr_unlock1(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n",
1600 base, cfi->addr_unlock1, map->size -1);
1604 if ((base + cfi->addr_unlock2) >= map->size) {
1606 "Probe at addr_unlock2(0x%08x + 0x%08x) past the end of the map(0x%08lx)\n",
1607 base, cfi->addr_unlock2, map->size -1);
1613 jedec_reset(base, map, cfi);
1615 /* Autoselect Mode */
1616 if(cfi->addr_unlock1) {
1617 cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1618 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1620 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
1621 /* FIXME - should have a delay before continuing */
1623 if (!cfi->numchips) {
1624 /* This is the first time we're called. Set up the CFI
1625 stuff accordingly and return */
1627 cfi->mfr = jedec_read_mfr(map, base, cfi);
1628 cfi->id = jedec_read_id(map, base, cfi);
1629 printk(KERN_INFO "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
1630 cfi->mfr, cfi->id, cfi->interleave, cfi->device_type);
1631 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
1632 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
1633 DEBUG( MTD_DEBUG_LEVEL3,
1634 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
1635 __func__, cfi->mfr, cfi->id,
1636 cfi->addr_unlock1, cfi->addr_unlock2 );
1637 if (!cfi_jedec_setup(cfi, i))
1642 switch(unlockpass++) {
1644 cfi->addr_unlock1 |= cfi->addr_unlock1 << 4;
1645 cfi->addr_unlock2 |= cfi->addr_unlock2 << 4;
1648 cfi->addr_unlock1 = cfi->addr_unlock2 = 0;
1656 /* Make sure it is a chip of the same manufacturer and id */
1657 mfr = jedec_read_mfr(map, base, cfi);
1658 id = jedec_read_id(map, base, cfi);
1660 if ((mfr != cfi->mfr) || (id != cfi->id)) {
1661 printk(KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n",
1662 map->name, mfr, id, base);
1663 jedec_reset(base, map, cfi);
1668 /* Check each previous chip to see if it's an alias */
1669 for (i=0; i<cfi->numchips; i++) {
1670 /* This chip should be in read mode if it's one
1671 we've already touched. */
1672 if (jedec_read_mfr(map, chips[i].start, cfi) == cfi->mfr &&
1673 jedec_read_id(map, chips[i].start, cfi) == cfi->id) {
1674 /* Eep. This chip also looks like it's in autoselect mode.
1675 Is it an alias for the new one? */
1676 jedec_reset(chips[i].start, map, cfi);
1678 /* If the device IDs go away, it's an alias */
1679 if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
1680 jedec_read_id(map, base, cfi) != cfi->id) {
1681 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
1682 map->name, base, chips[i].start);
1686 /* Yes, it's actually got the device IDs as data. Most
1687 * unfortunate. Stick the new chip in read mode
1688 * too and if it's the same, assume it's an alias. */
1689 /* FIXME: Use other modes to do a proper check */
1690 jedec_reset(base, map, cfi);
1691 if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
1692 jedec_read_id(map, base, cfi) == cfi->id) {
1693 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
1694 map->name, base, chips[i].start);
1700 /* OK, if we got to here, then none of the previous chips appear to
1701 be aliases for the current one. */
1702 if (cfi->numchips == MAX_CFI_CHIPS) {
1703 printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
1704 /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
1707 chips[cfi->numchips].start = base;
1708 chips[cfi->numchips].state = FL_READY;
1712 /* Put it back into Read Mode */
1713 jedec_reset(base, map, cfi);
1715 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n",
1716 map->name, cfi->interleave, cfi->device_type*8, base,
1722 static struct chip_probe jedec_chip_probe = {
1724 .probe_chip = jedec_probe_chip
1727 struct mtd_info *jedec_probe(struct map_info *map)
1730 * Just use the generic probe stuff to call our CFI-specific
1731 * chip_probe routine in all the possible permutations, etc.
1733 return mtd_do_chip_probe(map, &jedec_chip_probe);
1736 static struct mtd_chip_driver jedec_chipdrv = {
1737 .probe = jedec_probe,
1738 .name = "jedec_probe",
1739 .module = THIS_MODULE
1742 int __init jedec_probe_init(void)
1744 register_mtd_chip_driver(&jedec_chipdrv);
1748 static void __exit jedec_probe_exit(void)
1750 unregister_mtd_chip_driver(&jedec_chipdrv);
1753 module_init(jedec_probe_init);
1754 module_exit(jedec_probe_exit);
1756 MODULE_LICENSE("GPL");
1757 MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
1758 MODULE_DESCRIPTION("Probe code for JEDEC-compliant flash chips");