10 #include <linux/module.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>
26 #define AM29DL800BB 0x22CB
27 #define AM29DL800BT 0x224A
29 #define AM29F800BB 0x2258
30 #define AM29F800BT 0x22D6
31 #define AM29LV400BB 0x22BA
32 #define AM29LV400BT 0x22B9
33 #define AM29LV800BB 0x225B
34 #define AM29LV800BT 0x22DA
35 #define AM29LV160DT 0x22C4
36 #define AM29LV160DB 0x2249
37 #define AM29F017D 0x003D
38 #define AM29F016D 0x00AD
39 #define AM29F080 0x00D5
40 #define AM29F040 0x00A4
41 #define AM29LV040B 0x004F
42 #define AM29F032B 0x0041
43 #define AM29F002T 0x00B0
44 #define AM29SL800DB 0x226B
45 #define AM29SL800DT 0x22EA
48 #define AT49BV512 0x0003
49 #define AT29LV512 0x003d
50 #define AT49BV16X 0x00C0
51 #define AT49BV16XT 0x00C2
52 #define AT49BV32X 0x00C8
53 #define AT49BV32XT 0x00C9
56 #define EN29SL800BB 0x226B
57 #define EN29SL800BT 0x22EA
60 #define MBM29F040C 0x00A4
61 #define MBM29F800BA 0x2258
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
69 #define MBM29LV400TC 0x22B9
70 #define MBM29LV400BC 0x22BA
73 #define HY29F002T 0x00B0
76 #define I28F004B3T 0x00d4
77 #define I28F004B3B 0x00d5
78 #define I28F400B3T 0x8894
79 #define I28F400B3B 0x8895
80 #define I28F008S5 0x00a6
81 #define I28F016S5 0x00a0
82 #define I28F008SA 0x00a2
83 #define I28F008B3T 0x00d2
84 #define I28F008B3B 0x00d3
85 #define I28F800B3T 0x8892
86 #define I28F800B3B 0x8893
87 #define I28F016S3 0x00aa
88 #define I28F016B3T 0x00d0
89 #define I28F016B3B 0x00d1
90 #define I28F160B3T 0x8890
91 #define I28F160B3B 0x8891
92 #define I28F320B3T 0x8896
93 #define I28F320B3B 0x8897
94 #define I28F640B3T 0x8898
95 #define I28F640B3B 0x8899
96 #define I28F640C3B 0x88CD
97 #define I28F160F3T 0x88F3
98 #define I28F160F3B 0x88F4
99 #define I28F160C3T 0x88C2
100 #define I28F160C3B 0x88C3
101 #define I82802AB 0x00ad
102 #define I82802AC 0x00ac
105 #define MX29LV040C 0x004F
106 #define MX29LV160T 0x22C4
107 #define MX29LV160B 0x2249
108 #define MX29F040 0x00A4
109 #define MX29F016 0x00AD
110 #define MX29F002T 0x00B0
111 #define MX29F004T 0x0045
112 #define MX29F004B 0x0046
115 #define UPD29F064115 0x221C
118 #define PM49FL002 0x006D
119 #define PM49FL004 0x006E
120 #define PM49FL008 0x006A
123 #define LH28F640BF 0x00b0
126 #define M29F800AB 0x0058
127 #define M29W800DT 0x22D7
128 #define M29W800DB 0x225B
129 #define M29W400DT 0x00EE
130 #define M29W400DB 0x00EF
131 #define M29W160DT 0x22C4
132 #define M29W160DB 0x2249
133 #define M29W040B 0x00E3
134 #define M50FW040 0x002C
135 #define M50FW080 0x002D
136 #define M50FW016 0x002E
137 #define M50LPW080 0x002F
138 #define M50FLW080A 0x0080
139 #define M50FLW080B 0x0081
140 #define PSD4256G6V 0x00e9
143 #define SST29EE020 0x0010
144 #define SST29LE020 0x0012
145 #define SST29EE512 0x005d
146 #define SST29LE512 0x003d
147 #define SST39LF800 0x2781
148 #define SST39LF160 0x2782
149 #define SST39VF1601 0x234b
150 #define SST39VF3201 0x235b
151 #define SST39WF1601 0x274b
152 #define SST39WF1602 0x274a
153 #define SST39LF512 0x00D4
154 #define SST39LF010 0x00D5
155 #define SST39LF020 0x00D6
156 #define SST39LF040 0x00D7
157 #define SST39SF010A 0x00B5
158 #define SST39SF020A 0x00B6
159 #define SST39SF040 0x00B7
160 #define SST49LF004B 0x0060
161 #define SST49LF040B 0x0050
162 #define SST49LF008A 0x005a
163 #define SST49LF030A 0x001C
164 #define SST49LF040A 0x0051
165 #define SST49LF080A 0x005B
166 #define SST36VF3203 0x7354
169 #define TC58FVT160 0x00C2
170 #define TC58FVB160 0x0043
171 #define TC58FVT321 0x009A
172 #define TC58FVB321 0x009C
173 #define TC58FVT641 0x0093
174 #define TC58FVB641 0x0095
177 #define W49V002A 0x00b0
277 #define ERASEINFO(size,blocks) (size<<8)|(blocks-1)
279 #define SIZE_64KiB 16
280 #define SIZE_128KiB 17
281 #define SIZE_256KiB 18
282 #define SIZE_512KiB 19
298 .name =
"AMD AM29F032B",
310 .name =
"AMD AM29LV160DT",
325 .name =
"AMD AM29LV160DB",
340 .name =
"AMD AM29LV400BB",
355 .name =
"AMD AM29LV400BT",
370 .name =
"AMD AM29LV800BB",
386 .name =
"AMD AM29DL800BB",
403 .name =
"AMD AM29DL800BT",
420 .name =
"AMD AM29F800BB",
435 .name =
"AMD AM29LV800BT",
450 .name =
"AMD AM29F800BT",
465 .name =
"AMD AM29F017D",
477 .name =
"AMD AM29F016D",
489 .name =
"AMD AM29F080",
501 .name =
"AMD AM29F040",
513 .name =
"AMD AM29LV040B",
525 .name =
"AMD AM29F002T",
540 .name =
"AMD AM29SL800DT",
555 .name =
"AMD AM29SL800DB",
570 .name =
"Atmel AT49BV512",
582 .name =
"Atmel AT29LV512",
595 .name =
"Atmel AT49BV16X",
608 .name =
"Atmel AT49BV16XT",
621 .name =
"Atmel AT49BV32X",
634 .name =
"Atmel AT49BV32XT",
647 .name =
"Eon EN29SL800BT",
662 .name =
"Eon EN29SL800BB",
677 .name =
"Fujitsu MBM29F040C",
689 .name =
"Fujitsu MBM29F800BA",
704 .name =
"Fujitsu MBM29LV650UE",
716 .name =
"Fujitsu MBM29LV320TE",
729 .name =
"Fujitsu MBM29LV320BE",
742 .name =
"Fujitsu MBM29LV160TE",
757 .name =
"Fujitsu MBM29LV160BE",
772 .name =
"Fujitsu MBM29LV800BA",
787 .name =
"Fujitsu MBM29LV800TA",
802 .name =
"Fujitsu MBM29LV400BC",
817 .name =
"Fujitsu MBM29LV400TC",
832 .name =
"Hyundai HY29F002T",
847 .name =
"Intel 28F004B3B",
860 .name =
"Intel 28F004B3T",
873 .name =
"Intel 28F400B3B",
886 .name =
"Intel 28F400B3T",
899 .name =
"Intel 28F008B3B",
912 .name =
"Intel 28F008B3T",
925 .name =
"Intel 28F008S5",
937 .name =
"Intel 28F016S5",
949 .name =
"Intel 28F008SA",
961 .name =
"Intel 28F800B3B",
974 .name =
"Intel 28F800B3T",
987 .name =
"Intel 28F016B3B",
1000 .name =
"Intel I28F016S3",
1012 .name =
"Intel 28F016B3T",
1025 .name =
"Intel 28F160B3B",
1038 .name =
"Intel 28F160B3T",
1051 .name =
"Intel 28F320B3B",
1064 .name =
"Intel 28F320B3T",
1077 .name =
"Intel 28F640B3B",
1090 .name =
"Intel 28F640B3T",
1103 .name =
"Intel 28F640C3B",
1116 .name =
"Intel 82802AB",
1128 .name =
"Intel 82802AC",
1140 .name =
"Macronix MX29LV040C",
1152 .name =
"MXIC MX29LV160T",
1167 .name =
"NEC uPD29F064115",
1181 .name =
"MXIC MX29LV160B",
1196 .name =
"Macronix MX29F040",
1208 .name =
"Macronix MX29F016",
1220 .name =
"Macronix MX29F004T",
1235 .name =
"Macronix MX29F004B",
1250 .name =
"Macronix MX29F002T",
1265 .name =
"PMC Pm49FL002",
1277 .name =
"PMC Pm49FL004",
1289 .name =
"PMC Pm49FL008",
1301 .name =
"LH28F640BF",
1313 .name =
"SST 39LF512",
1325 .name =
"SST 39LF010",
1337 .name =
"SST 29EE020",
1348 .name =
"SST 29LE020",
1359 .name =
"SST 39LF020",
1371 .name =
"SST 39LF040",
1383 .name =
"SST 39SF010A",
1395 .name =
"SST 39SF020A",
1407 .name =
"SST 39SF040",
1419 .name =
"SST 49LF040B",
1432 .name =
"SST 49LF004B",
1444 .name =
"SST 49LF008A",
1456 .name =
"SST 49LF030A",
1468 .name =
"SST 49LF040A",
1480 .name =
"SST 49LF080A",
1492 .name =
"SST 39LF160",
1505 .name =
"SST 39VF1601",
1519 .name =
"SST 39WF1601",
1533 .name =
"SST 39WF1602",
1546 .name =
"SST 39VF3201",
1561 .name =
"SST 36VF3203",
1573 .name =
"ST M29F800AB",
1588 .name =
"ST M29W800DT",
1603 .name =
"ST M29W800DB",
1618 .name =
"ST M29W400DT",
1633 .name =
"ST M29W400DB",
1648 .name =
"ST M29W160DT",
1663 .name =
"ST M29W160DB",
1678 .name =
"ST M29W040B",
1690 .name =
"ST M50FW040",
1702 .name =
"ST M50FW080",
1714 .name =
"ST M50FW016",
1726 .name =
"ST M50LPW080",
1738 .name =
"ST M50FLW080A",
1753 .name =
"ST M50FLW080B",
1768 .name =
"ST PSD4256G6V",
1780 .name =
"Toshiba TC58FVT160",
1795 .name =
"Toshiba TC58FVB160",
1810 .name =
"Toshiba TC58FVB321",
1823 .name =
"Toshiba TC58FVT321",
1836 .name =
"Toshiba TC58FVB641",
1849 .name =
"Toshiba TC58FVT641",
1862 .name =
"Winbond W49V002A",
1889 uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi);
1891 result =
map_read(map, base + ofs);
1895 return result.
x[0] &
mask;
1903 u32 ofs = cfi_build_cmd_addr(1, map, cfi);
1905 result =
map_read(map, base + ofs);
1906 return result.
x[0] &
mask;
1920 pr_debug(
"reset unlock called %x %x \n",
1939 int i,num_erase_regions;
1943 pr_debug(
"Rejecting potential %s with incompatible %d-bit device type\n",
1966 for (i=0; i<num_erase_regions; i++){
1995 static inline int jedec_match(
uint32_t base,
2022 if (finfo->
dev_id > 0xff) {
2038 "MTD %s(): Unsupported device type %d\n",
2042 if ( cfi->
mfr != mfr || cfi->
id !=
id ) {
2047 pr_debug(
"MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
2049 if ( base + cfi_interleave(cfi) * ( 1 << finfo->
dev_size ) > map->
size ) {
2050 pr_debug(
"MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
2059 uaddr = finfo->
uaddr;
2061 pr_debug(
"MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
2066 pr_debug(
"MTD %s(): 0x%.4x 0x%.4x did not match\n",
2068 unlock_addrs[uaddr].
addr1,
2069 unlock_addrs[uaddr].
addr2);
2082 pr_debug(
"MTD %s(): check ID's disappear when not in ID mode\n",
2084 jedec_reset( base, map, cfi );
2085 mfr = jedec_read_mfr( map, base, cfi );
2086 id = jedec_read_id( map, base, cfi );
2087 if ( mfr == cfi->
mfr &&
id == cfi->
id ) {
2088 pr_debug(
"MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
2089 "You might need to manually specify JEDEC parameters.\n",
2090 __func__, cfi->
mfr, cfi->
id );
2101 pr_debug(
"MTD %s(): return to ID mode\n", __func__ );
2114 static int jedec_probe_chip(
struct map_info *map,
__u32 base,
2119 u32 probe_offset1, probe_offset2;
2133 if (base >= map->
size) {
2135 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
2136 base, map->
size -1);
2141 probe_offset1 = cfi_build_cmd_addr(cfi->
addr_unlock1, map, cfi);
2142 probe_offset2 = cfi_build_cmd_addr(cfi->
addr_unlock2, map, cfi);
2143 if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->
size) ||
2144 ((base + probe_offset2 + map_bankwidth(map)) >= map->
size))
2148 jedec_reset(base, map, cfi);
2162 cfi->
mfr = jedec_read_mfr(map, base, cfi);
2163 cfi->
id = jedec_read_id(map, base, cfi);
2164 pr_debug(
"Search for id:(%02x %02x) interleave(%d) type(%d)\n",
2166 for (i = 0; i <
ARRAY_SIZE(jedec_table); i++) {
2167 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
2168 pr_debug(
"MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
2169 __func__, cfi->
mfr, cfi->
id,
2171 if (!cfi_jedec_setup(map, cfi, i))
2182 mfr = jedec_read_mfr(map, base, cfi);
2183 id = jedec_read_id(map, base, cfi);
2185 if ((mfr != cfi->
mfr) || (
id != cfi->
id)) {
2186 printk(
KERN_DEBUG "%s: Found different chip or no chip at all (mfr 0x%x, id 0x%x) at 0x%x\n",
2187 map->
name, mfr,
id, base);
2188 jedec_reset(base, map, cfi);
2194 for (i=0; i < (base >> cfi->
chipshift); i++) {
2195 unsigned long start;
2200 if (jedec_read_mfr(map, start, cfi) == cfi->
mfr &&
2201 jedec_read_id(map, start, cfi) == cfi->
id) {
2204 jedec_reset(start, map, cfi);
2207 if (jedec_read_mfr(map, base, cfi) != cfi->
mfr ||
2208 jedec_read_id(map, base, cfi) != cfi->
id) {
2210 map->
name, base, start);
2218 jedec_reset(base, map, cfi);
2219 if (jedec_read_mfr(map, base, cfi) == cfi->
mfr &&
2220 jedec_read_id(map, base, cfi) == cfi->
id) {
2222 map->
name, base, start);
2235 jedec_reset(base, map, cfi);
2244 static struct chip_probe jedec_chip_probe = {
2246 .probe_chip = jedec_probe_chip
2259 .probe = jedec_probe,
2260 .name =
"jedec_probe",
2264 static int __init jedec_probe_init(
void)
2270 static void __exit jedec_probe_exit(
void)