⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jedec_probe.c

📁 基于linux-2.6.28的mtd驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/*   Common Flash Interface probe code.   (C) 2000 Red Hat. GPL'd.   See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)   for the standard this probe goes back to.   Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com*/#include <linux/module.h>#include <linux/init.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/mtd.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_EON	0x001c#define MANUFACTURER_FUJITSU	0x0004#define MANUFACTURER_HYUNDAI	0x00AD#define MANUFACTURER_INTEL	0x0089#define MANUFACTURER_MACRONIX	0x00C2#define MANUFACTURER_NEC	0x0010#define MANUFACTURER_PMC	0x009D#define MANUFACTURER_SHARP	0x00b0#define MANUFACTURER_SST	0x00BF#define MANUFACTURER_ST		0x0020#define MANUFACTURER_TOSHIBA	0x0098#define MANUFACTURER_WINBOND	0x00da#define CONTINUATION_CODE	0x007f/* AMD */#define AM29DL800BB	0x22CB#define AM29DL800BT	0x224A#define AM29F800BB	0x2258#define AM29F800BT	0x22D6#define AM29LV400BB	0x22BA#define AM29LV400BT	0x22B9#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#define AM29F002T	0x00B0#define AM29SL800DB	0x226B#define AM29SL800DT	0x22EA/* Atmel */#define AT49BV512	0x0003#define AT29LV512	0x003d#define AT49BV16X	0x00C0#define AT49BV16XT	0x00C2#define AT49BV32X	0x00C8#define AT49BV32XT	0x00C9/* Eon */#define EN29SL800BB	0x226B#define EN29SL800BT	0x22EA/* Fujitsu */#define MBM29F040C	0x00A4#define MBM29F800BA	0x2258#define MBM29LV650UE	0x22D7#define MBM29LV320TE	0x22F6#define MBM29LV320BE	0x22F9#define MBM29LV160TE	0x22C4#define MBM29LV160BE	0x2249#define MBM29LV800BA	0x225B#define MBM29LV800TA	0x22DA#define MBM29LV400TC	0x22B9#define MBM29LV400BC	0x22BA/* Hyundai */#define HY29F002T	0x00B0/* 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 MX29LV040C	0x004F#define MX29LV160T	0x22C4#define MX29LV160B	0x2249#define MX29F040	0x00A4#define MX29F016	0x00AD#define MX29F002T	0x00B0#define MX29F004T	0x0045#define MX29F004B	0x0046/* NEC */#define UPD29F064115	0x221C/* PMC */#define PM49FL002	0x006D#define PM49FL004	0x006E#define PM49FL008	0x006A/* Sharp */#define LH28F640BF	0x00b0/* ST - www.st.com */#define M29F800AB	0x0058#define M29W800DT	0x00D7#define M29W800DB	0x005B#define M29W400DT	0x00EE#define M29W400DB	0x00EF#define M29W160DT	0x22C4#define M29W160DB	0x2249#define M29W040B	0x00E3#define M50FW040	0x002C#define M50FW080	0x002D#define M50FW016	0x002E#define M50LPW080       0x002F#define M50FLW080A	0x0080#define M50FLW080B	0x0081/* SST */#define SST29EE020	0x0010#define SST29LE020	0x0012#define SST29EE512	0x005d#define SST29LE512	0x003d#define SST39LF800	0x2781#define SST39LF160	0x2782#define SST39VF1601	0x234b#define SST39LF512	0x00D4#define SST39LF010	0x00D5#define SST39LF020	0x00D6#define SST39LF040	0x00D7#define SST39SF010A	0x00B5#define SST39SF020A	0x00B6#define SST49LF004B	0x0060#define SST49LF040B	0x0050#define SST49LF008A	0x005a#define SST49LF030A	0x001C#define SST49LF040A	0x0051#define SST49LF080A	0x005B#define SST36VF3203	0x7354/* 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_0xAAAA_0x5555,	MTD_UADDR_DONT_CARE,		/* Requires an arbitrary address */	MTD_UADDR_UNNECESSARY,		/* Does not require any address */};struct unlock_addr {	uint32_t addr1;	uint32_t 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_0xAAAA_0x5555] = {		.addr1 = 0xaaaa,		.addr2 = 0x5555	},	[MTD_UADDR_DONT_CARE] = {		.addr1 = 0x0000,      /* Doesn't matter which address */		.addr2 = 0x0000       /* is used - must be last entry */	},	[MTD_UADDR_UNNECESSARY] = {		.addr1 = 0x0000,		.addr2 = 0x0000	}};struct amd_flash_info {	const char *name;	const uint16_t mfr_id;	const uint16_t dev_id;	const uint8_t dev_size;	const uint8_t nr_regions;	const uint16_t cmd_set;	const uint32_t regions[6];	const uint8_t devtypes;		/* Bitmask for x8, x16 etc. */	const uint8_t uaddr;		/* unlock addrs for 8, 16, 32, 64 */};#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		= MTD_UADDR_0x0555_0x02AA,		.devtypes	= CFI_DEVICETYPE_X8,		.dev_size	= SIZE_4MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 1,		.regions	= {			ERASEINFO(0x10000,64)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29LV160DT,		.name		= "AMD AM29LV160DT",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_2MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x10000,31),			ERASEINFO(0x08000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x04000,1)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29LV160DB,		.name		= "AMD AM29LV160DB",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_2MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x04000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x08000,1),			ERASEINFO(0x10000,31)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29LV400BB,		.name		= "AMD AM29LV400BB",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_512KiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x04000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x08000,1),			ERASEINFO(0x10000,7)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29LV400BT,		.name		= "AMD AM29LV400BT",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_512KiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x10000,7),			ERASEINFO(0x08000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x04000,1)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29LV800BB,		.name		= "AMD AM29LV800BB",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_1MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x04000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x08000,1),			ERASEINFO(0x10000,15),		}	}, {/* add DL */		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29DL800BB,		.name		= "AMD AM29DL800BB",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_1MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 6,		.regions	= {			ERASEINFO(0x04000,1),			ERASEINFO(0x08000,1),			ERASEINFO(0x02000,4),			ERASEINFO(0x08000,1),			ERASEINFO(0x04000,1),			ERASEINFO(0x10000,14)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29DL800BT,		.name		= "AMD AM29DL800BT",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_1MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 6,		.regions	= {			ERASEINFO(0x10000,14),			ERASEINFO(0x04000,1),			ERASEINFO(0x08000,1),			ERASEINFO(0x02000,4),			ERASEINFO(0x08000,1),			ERASEINFO(0x04000,1)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29F800BB,		.name		= "AMD AM29F800BB",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_1MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x04000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x08000,1),			ERASEINFO(0x10000,15),		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29LV800BT,		.name		= "AMD AM29LV800BT",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_1MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x10000,15),			ERASEINFO(0x08000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x04000,1)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29F800BT,		.name		= "AMD AM29F800BT",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_1MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x10000,15),			ERASEINFO(0x08000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x04000,1)		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29F017D,		.name		= "AMD AM29F017D",		.devtypes	= CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_DONT_CARE,		.dev_size	= SIZE_2MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 1,		.regions	= {			ERASEINFO(0x10000,32),		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29F016D,		.name		= "AMD AM29F016D",		.devtypes	= CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0555_0x02AA,		.dev_size	= SIZE_2MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 1,		.regions	= {			ERASEINFO(0x10000,32),		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29F080,		.name		= "AMD AM29F080",		.devtypes	= CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0555_0x02AA,		.dev_size	= SIZE_1MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 1,		.regions	= {			ERASEINFO(0x10000,16),		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29F040,		.name		= "AMD AM29F040",		.devtypes	= CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0555_0x02AA,		.dev_size	= SIZE_512KiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 1,		.regions	= {			ERASEINFO(0x10000,8),		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29LV040B,		.name		= "AMD AM29LV040B",		.devtypes	= CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0555_0x02AA,		.dev_size	= SIZE_512KiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 1,		.regions	= {			ERASEINFO(0x10000,8),		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29F002T,		.name		= "AMD AM29F002T",		.devtypes	= CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0555_0x02AA,		.dev_size	= SIZE_256KiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x10000,3),			ERASEINFO(0x08000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x04000,1),		}	}, {		.mfr_id		= MANUFACTURER_AMD,		.dev_id		= AM29SL800DT,		.name		= "AMD AM29SL800DT",		.devtypes	= CFI_DEVICETYPE_X16|CFI_DEVICETYPE_X8,		.uaddr		= MTD_UADDR_0x0AAA_0x0555,		.dev_size	= SIZE_1MiB,		.cmd_set	= P_ID_AMD_STD,		.nr_regions	= 4,		.regions	= {			ERASEINFO(0x10000,15),			ERASEINFO(0x08000,1),			ERASEINFO(0x02000,2),			ERASEINFO(0x04000,1),		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -