[U-Boot] [PATCH V3 1/2] mtd/spi/spi_flash: support CMD_READ_ID=0x90 case

Mikhail Kshevetskiy mikhail.kshevetskiy at gmail.com
Mon Jul 9 20:53:20 CEST 2012


current code does not support spi flashes that have 0x90 read_id command,
so fix this

Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy at gmail.com>
---
Change for v3:
 * split SPI flash fixes to separate patch series (series 2/3)
Change for v2:
 * fix checkpatch warnings
---
 drivers/mtd/spi/spi_flash.c          |   66 +++++++++++++++++++++++-----------
 drivers/mtd/spi/spi_flash_internal.h |    1 +
 2 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index f689cc4..530b7b3 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -306,13 +306,44 @@ static const struct {
 };
 #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
 
+struct spi_flash *spi_analize_flash_probe(struct spi_slave *spi,
+		u8 *idcode, size_t idcode_len, u8 *id)
+{
+	struct spi_flash *flash = NULL;
+	int i, shift;
+	u8 *idp;
+
+#ifdef DEBUG
+	printf("SF: Got idcodes\n");
+	print_buffer(0, idcode, 1, idcode_len, 0);
+#endif
+
+	/* count the number of continuation bytes */
+	for (shift = 0, idp = idcode;
+	     shift < idcode_len && *idp == 0x7f;
+	     ++shift, ++idp)
+		continue;
+
+	*id = *idp;
+	/* search the table for matches in shift and id */
+	for (i = 0; i < ARRAY_SIZE(flashes); ++i)
+		if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
+			/* we have a match, call probe */
+			flash = flashes[i].probe(spi, idp);
+			if (flash)
+				break;
+		}
+
+	return flash;
+}
+
 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
 		unsigned int max_hz, unsigned int spi_mode)
 {
 	struct spi_slave *spi;
 	struct spi_flash *flash = NULL;
-	int ret, i, shift;
-	u8 idcode[IDCODE_LEN], *idp;
+	u8 cmd[4], idcode[IDCODE_LEN], id;
+	int ret;
 
 	spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
 	if (!spi) {
@@ -331,28 +362,23 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
 	if (ret)
 		goto err_read_id;
 
-#ifdef DEBUG
-	printf("SF: Got idcodes\n");
-	print_buffer(0, idcode, 1, sizeof(idcode), 0);
-#endif
+	flash = spi_analize_flash_probe(spi, idcode, sizeof(idcode), &id);
+	if (id == 0xff) {
+		/* try CMD_READ_ID_NEW command */
+		cmd[0] = CMD_READ_ID_NEW;
+		spi_flash_addr(0x000000, cmd);
 
-	/* count the number of continuation bytes */
-	for (shift = 0, idp = idcode;
-	     shift < IDCODE_CONT_LEN && *idp == 0x7f;
-	     ++shift, ++idp)
-		continue;
+		ret = spi_flash_cmd_read(spi, cmd, sizeof(cmd),
+					idcode, sizeof(idcode));
+		if (ret)
+			goto err_read_id;
 
-	/* search the table for matches in shift and id */
-	for (i = 0; i < ARRAY_SIZE(flashes); ++i)
-		if (flashes[i].shift == shift && flashes[i].idcode == *idp) {
-			/* we have a match, call probe */
-			flash = flashes[i].probe(spi, idp);
-			if (flash)
-				break;
-		}
+		flash = spi_analize_flash_probe(spi,
+					idcode, sizeof(idcode), &id);
+	}
 
 	if (!flash) {
-		printf("SF: Unsupported manufacturer %02x\n", *idp);
+		printf("SF: Unsupported manufacturer %02x\n", id);
 		goto err_manufacturer_probe;
 	}
 
diff --git a/drivers/mtd/spi/spi_flash_internal.h b/drivers/mtd/spi/spi_flash_internal.h
index 91e036a..b8bd5d5 100644
--- a/drivers/mtd/spi/spi_flash_internal.h
+++ b/drivers/mtd/spi/spi_flash_internal.h
@@ -14,6 +14,7 @@
 
 /* Common commands */
 #define CMD_READ_ID			0x9f
+#define CMD_READ_ID_NEW			0x90
 
 #define CMD_READ_ARRAY_SLOW		0x03
 #define CMD_READ_ARRAY_FAST		0x0b
-- 
1.7.10.4



More information about the U-Boot mailing list