📄 jedec_probe.c
字号:
/* Common Flash Interface probe code. (C) 2000 Red Hat. GPL'd. $Id: jedec_probe.c,v 1.25 2003/04/18 16:00:57 thayne Exp $ See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) for the standard this probe goes back to.*/#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <asm/io.h>#include <asm/byteorder.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/mtd/map.h>#include <linux/mtd/cfi.h>#include <linux/mtd/gen_probe.h>/* Manufacturers */#define MANUFACTURER_AMD 0x0001#define MANUFACTURER_ATMEL 0x001f#define MANUFACTURER_FUJITSU 0x0004#define MANUFACTURER_INTEL 0x0089#define MANUFACTURER_MACRONIX 0x00C2#define MANUFACTURER_PMC 0x009D#define MANUFACTURER_SST 0x00BF#define MANUFACTURER_ST 0x0020#define MANUFACTURER_TOSHIBA 0x0098#define MANUFACTURER_WINBOND 0x00da/* AMD */#define AM29F800BB 0x2258#define AM29F800BT 0x22D6#define AM29LV800BB 0x225B#define AM29LV800BT 0x22DA#define AM29LV160DT 0x22C4#define AM29LV160DB 0x2249#define AM29F017D 0x003D#define AM29F016D 0x00AD#define AM29F080 0x00D5#define AM29F040 0x00A4#define AM29LV040B 0x004F#define AM29F032B 0x0041/* Atmel */#define AT49BV512 0x0003#define AT29LV512 0x003d#define AT49BV16X 0x00C0#define AT49BV16XT 0x00C2#define AT49BV32X 0x00C8#define AT49BV32XT 0x00C9/* Fujitsu */#define MBM29LV650UE 0x22D7#define MBM29LV320TE 0x22F6#define MBM29LV320BE 0x22F9#define MBM29LV160TE 0x22C4#define MBM29LV160BE 0x2249#define MBM29LV800BA 0x225B#define MBM29LV800TA 0x22DA/* Intel */#define I28F004B3T 0x00d4#define I28F004B3B 0x00d5#define I28F400B3T 0x8894#define I28F400B3B 0x8895#define I28F008S5 0x00a6#define I28F016S5 0x00a0#define I28F008SA 0x00a2#define I28F008B3T 0x00d2#define I28F008B3B 0x00d3#define I28F800B3T 0x8892#define I28F800B3B 0x8893#define I28F016S3 0x00aa#define I28F016B3T 0x00d0#define I28F016B3B 0x00d1#define I28F160B3T 0x8890#define I28F160B3B 0x8891#define I28F320B3T 0x8896#define I28F320B3B 0x8897#define I28F640B3T 0x8898#define I28F640B3B 0x8899#define I82802AB 0x00ad#define I82802AC 0x00ac/* Macronix */#define MX29LV160T 0x22C4#define MX29LV160B 0x2249#define MX29F016 0x00AD#define MX29F004T 0x0045#define MX29F004B 0x0046/* PMC */#define PM49FL002 0x006D#define PM49FL004 0x006E#define PM49FL008 0x006A/* ST - www.st.com */#define M29W800DT 0x00D7#define M29W800DB 0x005B#define M29W160DT 0x22C4#define M29W160DB 0x2249#define M29W040B 0x00E3/* SST */#define SST29EE512 0x005d#define SST29LE512 0x003d#define SST39LF800 0x2781#define SST39LF160 0x2782#define SST39LF512 0x00D4#define SST39LF010 0x00D5#define SST39LF020 0x00D6#define SST39LF040 0x00D7#define SST39SF010A 0x00B5#define SST39SF020A 0x00B6#define SST49LF030A 0x001C#define SST49LF040A 0x0051#define SST49LF080A 0x005B/* Toshiba */#define TC58FVT160 0x00C2#define TC58FVB160 0x0043#define TC58FVT321 0x009A#define TC58FVB321 0x009C#define TC58FVT641 0x0093#define TC58FVB641 0x0095/* Winbond */#define W49V002A 0x00b0/* * Unlock address sets for AMD command sets. * Intel command sets use the MTD_UADDR_UNNECESSARY. * Each identifier, except MTD_UADDR_UNNECESSARY, and * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[]. * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure * initialization need not require initializing all of the * unlock addresses for all bit widths. */enum uaddr { MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */ MTD_UADDR_0x0555_0x02AA, MTD_UADDR_0x0555_0x0AAA, MTD_UADDR_0x5555_0x2AAA, MTD_UADDR_0x0AAA_0x0555, MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */ MTD_UADDR_UNNECESSARY, /* Does not require any address */};struct unlock_addr { int addr1; int addr2;};/* * I don't like the fact that the first entry in unlock_addrs[] * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore, * should not be used. The problem is that structures with * initializers have extra fields initialized to 0. It is _very_ * desireable to have the unlock address entries for unsupported * data widths automatically initialized - that means that * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here * must go unused. */static const struct unlock_addr unlock_addrs[] = { [MTD_UADDR_NOT_SUPPORTED] = { .addr1 = 0xffff, .addr2 = 0xffff }, [MTD_UADDR_0x0555_0x02AA] = { .addr1 = 0x0555, .addr2 = 0x02aa }, [MTD_UADDR_0x0555_0x0AAA] = { .addr1 = 0x0555, .addr2 = 0x0aaa }, [MTD_UADDR_0x5555_0x2AAA] = { .addr1 = 0x5555, .addr2 = 0x2aaa }, [MTD_UADDR_0x0AAA_0x0555] = { .addr1 = 0x0AAA, .addr2 = 0x0555 }, [MTD_UADDR_DONT_CARE] = { .addr1 = 0x0000, /* Doesn't matter which address */ .addr2 = 0x0000 /* is used - must be last entry */ }};struct amd_flash_info { const __u16 mfr_id; const __u16 dev_id; const char *name; const int DevSize; const int InterfaceDesc; const int NumEraseRegions; const int CmdSet; const __u8 uaddr[3]; /* unlock addrs for 8, 16, 32 modes */ const ulong regions[4];};#define ERASEINFO(size,blocks) (size<<8)|(blocks-1)#define SIZE_64KiB 16#define SIZE_128KiB 17#define SIZE_256KiB 18#define SIZE_512KiB 19#define SIZE_1MiB 20#define SIZE_2MiB 21#define SIZE_4MiB 22#define SIZE_8MiB 23/* * Please keep this list ordered by manufacturer! * Fortunately, the list isn't searched often and so a * slow, linear search isn't so bad. */static const struct amd_flash_info jedec_table[] = { { mfr_id: MANUFACTURER_AMD, dev_id: AM29F032B, name: "AMD AM29F032B", uaddr: {[0] = MTD_UADDR_0x0555_0x02AA}, /* x8 */ DevSize: SIZE_4MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,64) } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29LV160DT, name: "AMD AM29LV160DT", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ }, DevSize: SIZE_2MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 4, regions: {ERASEINFO(0x10000,31), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29LV160DB, name: "AMD AM29LV160DB", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */ }, DevSize: SIZE_2MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 4, regions: {ERASEINFO(0x04000,1), ERASEINFO(0x02000,2), ERASEINFO(0x08000,1), ERASEINFO(0x10000,31) } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29LV800BB, name: "AMD AM29LV800BB", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ }, DevSize: SIZE_1MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 4, regions: {ERASEINFO(0x04000,1), ERASEINFO(0x02000,2), ERASEINFO(0x08000,1), ERASEINFO(0x10000,15), } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29F800BB, name: "AMD AM29F800BB", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ }, DevSize: SIZE_1MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 4, regions: {ERASEINFO(0x04000,1), ERASEINFO(0x02000,2), ERASEINFO(0x08000,1), ERASEINFO(0x10000,15), } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29LV800BT, name: "AMD AM29LV800BT", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ }, DevSize: SIZE_1MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 4, regions: {ERASEINFO(0x10000,15), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29F800BT, name: "AMD AM29F800BT", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ }, DevSize: SIZE_1MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 4, regions: {ERASEINFO(0x10000,15), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29F017D, name: "AMD AM29F017D", uaddr: {[0] = MTD_UADDR_DONT_CARE}, /* x8 */ DevSize: SIZE_2MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,32), } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29F016D, name: "AMD AM29F016D", uaddr: {[0] = MTD_UADDR_0x0555_0x02AA}, /* x8 */ DevSize: SIZE_2MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,32), } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29F080, name: "AMD AM29F080", uaddr: {[0] = MTD_UADDR_0x0555_0x02AA}, /* x8 */ DevSize: SIZE_1MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,16), } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29F040, name: "AMD AM29F040", uaddr: {[0] = MTD_UADDR_0x0555_0x02AA}, /* x8 */ DevSize: SIZE_512KiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,8), } }, { mfr_id: MANUFACTURER_AMD, dev_id: AM29LV040B, name: "AMD AM29LV040B", uaddr: {[0] = MTD_UADDR_0x0555_0x02AA}, /* x8 */ DevSize: SIZE_512KiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,8), } }, { mfr_id: MANUFACTURER_ATMEL, dev_id: AT49BV512, name: "Atmel AT49BV512", uaddr: {[0] = MTD_UADDR_0x5555_0x2AAA}, /* x8 */ DevSize: SIZE_64KiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,1) } }, { mfr_id: MANUFACTURER_ATMEL, dev_id: AT29LV512, name: "Atmel AT29LV512", uaddr: {[0] = MTD_UADDR_0x5555_0x2AAA}, /* x8 */ DevSize: SIZE_64KiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: { ERASEINFO(0x80,256), ERASEINFO(0x80,256) } }, { mfr_id: MANUFACTURER_ATMEL, dev_id: AT49BV16X, name: "Atmel AT49BV16X", uaddr: {[0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ }, DevSize: SIZE_2MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 2, regions: {ERASEINFO(0x02000,8), ERASEINFO(0x10000,31) } }, { mfr_id: MANUFACTURER_ATMEL, dev_id: AT49BV16XT, name: "Atmel AT49BV16XT", uaddr: {[0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ }, DevSize: SIZE_2MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 2, regions: {ERASEINFO(0x10000,31), ERASEINFO(0x02000,8) } }, { mfr_id: MANUFACTURER_ATMEL, dev_id: AT49BV32X, name: "Atmel AT49BV32X", uaddr: {[0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ }, DevSize: SIZE_4MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 2, regions: {ERASEINFO(0x02000,8), ERASEINFO(0x10000,63) } }, { mfr_id: MANUFACTURER_ATMEL, dev_id: AT49BV32XT, name: "Atmel AT49BV32XT", uaddr: {[0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */ }, DevSize: SIZE_4MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 2, regions: {ERASEINFO(0x10000,63), ERASEINFO(0x02000,8) } }, { mfr_id: MANUFACTURER_FUJITSU, dev_id: MBM29LV650UE, name: "Fujitsu MBM29LV650UE", uaddr: {[0] = MTD_UADDR_DONT_CARE}, /* x16 */ DevSize: SIZE_8MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,128) } }, { mfr_id: MANUFACTURER_FUJITSU, dev_id: MBM29LV320TE, name: "Fujitsu MBM29LV320TE", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ }, DevSize: SIZE_4MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 2, regions: {ERASEINFO(0x10000,63), ERASEINFO(0x02000,8) } }, { mfr_id: MANUFACTURER_FUJITSU, dev_id: MBM29LV320BE, name: "Fujitsu MBM29LV320BE", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ }, DevSize: SIZE_4MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 2, regions: {ERASEINFO(0x02000,8), ERASEINFO(0x10000,63) } }, { mfr_id: MANUFACTURER_FUJITSU, dev_id: MBM29LV160TE, name: "Fujitsu MBM29LV160TE", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ }, DevSize: SIZE_2MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 4, regions: {ERASEINFO(0x10000,31), ERASEINFO(0x08000,1), ERASEINFO(0x02000,2), ERASEINFO(0x04000,1) } }, { mfr_id: MANUFACTURER_FUJITSU, dev_id: MBM29LV160BE, name: "Fujitsu MBM29LV160BE", uaddr: {[0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */ }, DevSize: SIZE_2MiB, CmdSet: P_ID_AMD_STD, NumEraseRegions: 4, regions: {ERASEINFO(0x04000,1), ERASEINFO(0x02000,2), ERASEINFO(0x08000,1), ERASEINFO(0x10000,31) } }, { mfr_id: MANUFACTURER_FUJITSU,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -