[PATCH v4 1/6] mtd: spi-nor: Add manufacturer read id function
Jaime Liao
jaimeliao.tw at gmail.com
Thu Sep 7 23:42:59 PDT 2023
From: JaimeLiao <jaimeliao at mxic.com.tw>
Add manufacturer read id function because of some flash
may change data format when read id in octal dtr mode.
Signed-off-by: JaimeLiao <jaimeliao at mxic.com.tw>
---
drivers/mtd/spi-nor/core.c | 30 ++++++++++++++++++++++++++++--
drivers/mtd/spi-nor/core.h | 6 ++++++
drivers/mtd/spi-nor/macronix.c | 18 ++++++++++++++++++
3 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 1b0c6770c14e..7ee624b16e17 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -408,7 +408,7 @@ int spi_nor_write_disable(struct spi_nor *nor)
}
/**
- * spi_nor_read_id() - Read the JEDEC ID.
+ * spi_nor_default_read_id() - Read the JEDEC ID.
* @nor: pointer to 'struct spi_nor'.
* @naddr: number of address bytes to send. Can be zero if the operation
* does not need to send an address.
@@ -420,7 +420,7 @@ int spi_nor_write_disable(struct spi_nor *nor)
*
* Return: 0 on success, -errno otherwise.
*/
-int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
+int spi_nor_default_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
enum spi_nor_protocol proto)
{
int ret;
@@ -438,6 +438,32 @@ int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
return ret;
}
+/**
+ * spi_nor_read_id() - Read ID by manufacturer read id function.
+ * @nor: pointer to 'struct spi_nor'.
+ * @naddr: number of address bytes to send. Can be zero if the operation
+ * does not need to send an address.
+ * @ndummy: number of dummy bytes to send after an opcode or address. Can
+ * be zero if the operation does not require dummy bytes.
+ * @id: pointer to a DMA-able buffer where the value of the JEDEC ID
+ * will be written.
+ * @proto: the SPI protocol for register operation.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
+ enum spi_nor_protocol proto)
+{
+ int ret;
+
+ if (nor->manufacturer && nor->manufacturer->fixups && nor->manufacturer->fixups->read_id)
+ ret = nor->manufacturer->fixups->read_id(nor, naddr, ndummy, id, proto);
+ else
+ ret = spi_nor_default_read_id(nor, naddr, ndummy, id, proto);
+
+ return ret;
+}
+
/**
* spi_nor_read_sr() - Read the Status Register.
* @nor: pointer to 'struct spi_nor'.
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 9217379b9cfe..92cbc2d3f7fe 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -424,6 +424,8 @@ struct spi_nor_flash_parameter {
* @late_init: used to initialize flash parameters that are not declared in the
* JESD216 SFDP standard, or where SFDP tables not defined at all.
* Will replace the default_init() hook.
+ * @read_id: used to read id which may change format after enter into
+ octal dtr mode.
*
* Those hooks can be used to tweak the SPI NOR configuration when the SFDP
* table is broken or not available.
@@ -435,6 +437,8 @@ struct spi_nor_fixups {
const struct sfdp_bfpt *bfpt);
int (*post_sfdp)(struct spi_nor *nor);
int (*late_init)(struct spi_nor *nor);
+ int (*read_id)(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
+ enum spi_nor_protocol reg_proto);
};
/**
@@ -667,6 +671,8 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor);
int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor);
int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor);
int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor);
+int spi_nor_default_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
+ enum spi_nor_protocol reg_proto);
int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
enum spi_nor_protocol reg_proto);
int spi_nor_read_sr(struct spi_nor *nor, u8 *sr);
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index eb149e517c1f..8ab47691dfbb 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -118,9 +118,27 @@ static int macronix_nor_late_init(struct spi_nor *nor)
return 0;
}
+static int macronix_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
+ enum spi_nor_protocol proto)
+{
+ int i, ret;
+
+ ret = spi_nor_default_read_id(nor, naddr, ndummy, id, proto);
+ /* Retrieve odd array and re-sort id because of read id format will be A-A-B-B-C-C
+ * after enter into octal dtr mode for Macronix flashes.
+ */
+ if (proto == SNOR_PROTO_8_8_8_DTR) {
+ for (i = 0; i < nor->info->id_len; i++)
+ id[i] = id[i*2];
+ }
+
+ return ret;
+}
+
static const struct spi_nor_fixups macronix_nor_fixups = {
.default_init = macronix_nor_default_init,
.late_init = macronix_nor_late_init,
+ .read_id = macronix_nor_read_id,
};
const struct spi_nor_manufacturer spi_nor_macronix = {
--
2.25.1
More information about the linux-mtd
mailing list