[PATCH] mtd: m25p80.c add support for non-JEDEC ID devices
hartleys
hartleys at visionengravers.com
Mon Oct 13 17:20:49 EDT 2008
Hello all,
This patch allows the m25p80 driver to support non-JEDEC ID devices.
It has been tested on an EP93xx based ARM platform with a SST25LF020A
2Mbit SPI Serial Flash device.
Any comments would be appreciated.
Thanks,
Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
---
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index b35c333..ee6dd52 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -41,6 +41,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_NON_JEDEC 0x90 /* Read non-JEDEC ID */
/* Status Register bits. */
#define SR_WIP 1 /* Write in progress */
@@ -507,13 +508,17 @@ static struct flash_info __devinitdata m25p_data
[] = {
{ "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
{ "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
{ "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
+
+ /* Non JEDEC ID 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;
@@ -521,7 +526,8 @@ static struct flash_info *__devinit
jedec_probe(struct spi_device *spi)
* 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);
@@ -540,6 +546,31 @@ static struct flash_info *__devinit
jedec_probe(struct spi_device *spi)
return info;
}
dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
+
+ /* Try reading the non-JEDEC Manufacture/Device ID */
+ code[0] = OPCODE_RDID_NON_JEDEC;
+ 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