[PATCH] mtd: m25p80.c add support for non-JEDEC ID devices

hartleys hartleys at visionengravers.com
Fri Jul 25 12:34:17 EDT 2008


The following patch adds support for the SST 2 Mbit / 4 Mbit SPI Serial
Flash devices (SST25LF020A/SST25LF040A).

These devices do not support the JEDEC-Read-ID command but they do have
a Read-ID command. There are probably other SPI serial flash devices
there that could be used with the same patch.


Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>


--- orig/linux-2.6.25.10/drivers/mtd/devices/m25p80.c	2008-07-02
20:46:47.000000000 -0700
+++
/home/bigguiness/buildroot/project_build_arm/ep9307/linux-2.6.25.10/driv
ers/mtd/devices/m25p80.c	2008-07-24 15:10:33.000000000 -0700
@@ -40,6 +40,7 @@
 #define	OPCODE_BE_32K		0x52	/* Erase 32KiB block */
 #define	OPCODE_SE		0xd8	/* Sector erase (usually
64KiB) */
 #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
+#define OPCODE_RDID_90		0x90	/* Read ID */
 
 /* Status Register bits. */
 #define	SR_WIP			1	/* Write in progress */
@@ -481,13 +482,17 @@ static struct flash_info __devinitdata m
 	{ "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
 	{ "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
 	{ "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
+
+	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
+	{ "sst25lf020a", 0xbf43, 32 * 1024, 8, SECT_4K, },
+	{ "sst25lf040a", 0xbf44, 32 * 1024, 16, SECT_4K, },
 };
 
 static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
 {
 	int			tmp;
-	u8			code = OPCODE_RDID;
-	u8			id[3];
+	u8			code[4];
+	u8			id[4];
 	u32			jedec;
 	struct flash_info	*info;
 
@@ -495,7 +500,8 @@ static struct flash_info *__devinit jede
 	 * string for after vendor-specific data, after the three bytes
 	 * we use here.  Supporting some chips might require using it.
 	 */
-	tmp = spi_write_then_read(spi, &code, 1, id, 3);
+	code[0] = OPCODE_RDID;
+	tmp = spi_write_then_read(spi, code, 1, id, 3);
 	if (tmp < 0) {
 		DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC
ID\n",
 			spi->dev.bus_id, tmp);
@@ -514,6 +520,30 @@ static struct flash_info *__devinit jede
 			return info;
 	}
 	dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
+
+	/* Try reading the Manufacture/Device ID with the alternate
opcode */
+	code[0] = OPCODE_RDID_90;
+	code[1] = 0x00;
+	code[2] = 0x00;
+	code[3] = 0x00;
+	tmp = spi_write_then_read(spi, code, 4, id, 2);
+	if (tmp < 0) {
+		DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading ID\n",
+			spi->dev.bus_id, tmp);
+		return NULL;
+	}
+
+	jedec = id[0];
+	jedec = jedec << 8;
+	jedec |= id[1];
+
+	for (tmp = 0, info = m25p_data;
+			tmp < ARRAY_SIZE(m25p_data);
+			tmp++, info++) {
+		if (info->jedec_id == jedec)
+			return info;
+	}
+	dev_err(&spi->dev, "unrecognized id %04x\n", jedec);
 	return NULL;
 }
  



More information about the linux-mtd mailing list