diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/spi-nor/core.c | 50 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/core.h | 9 |
2 files changed, 44 insertions, 15 deletions
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 386e81a3b12e..f74fdbf1d4c9 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -370,6 +370,37 @@ int spi_nor_write_disable(struct spi_nor *nor) } /** + * spi_nor_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. + * @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->spimem) { + struct spi_mem_op op = + SPI_NOR_READID_OP(naddr, ndummy, id, SPI_NOR_MAX_ID_LEN); + + spi_nor_spimem_setup_op(nor, &op, proto); + ret = spi_mem_exec_op(nor->spimem, &op); + } else { + ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDID, id, + SPI_NOR_MAX_ID_LEN); + } + return ret; +} + +/** * spi_nor_read_sr() - Read the Status Register. * @nor: pointer to 'struct spi_nor'. * @sr: pointer to a DMA-able buffer where the value of the @@ -1658,24 +1689,13 @@ static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, return NULL; } -static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) +static const struct flash_info *spi_nor_detect(struct spi_nor *nor) { const struct flash_info *info; u8 *id = nor->bouncebuf; int ret; - if (nor->spimem) { - struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1), - SPI_MEM_OP_NO_ADDR, - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_IN(SPI_NOR_MAX_ID_LEN, id, 1)); - - ret = spi_mem_exec_op(nor->spimem, &op); - } else { - ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDID, id, - SPI_NOR_MAX_ID_LEN); - } + ret = spi_nor_read_id(nor, 0, 0, id, nor->reg_proto); if (ret) { dev_dbg(nor->dev, "error %d reading JEDEC ID\n", ret); return ERR_PTR(ret); @@ -2909,7 +2929,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor, info = spi_nor_match_name(nor, name); /* Try to auto-detect if chip name wasn't specified or not found */ if (!info) - return spi_nor_read_id(nor); + return spi_nor_detect(nor); /* * If caller has specified name of flash model that can normally be @@ -2918,7 +2938,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor, if (name && info->id_len) { const struct flash_info *jinfo; - jinfo = spi_nor_read_id(nor); + jinfo = spi_nor_detect(nor); if (IS_ERR(jinfo)) { return jinfo; } else if (jinfo != info) { diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index b7fd760e3b47..f952061d5c24 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -11,6 +11,13 @@ #define SPI_NOR_MAX_ID_LEN 6 +/* Standard SPI NOR flash operations. */ +#define SPI_NOR_READID_OP(naddr, ndummy, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 0), \ + SPI_MEM_OP_ADDR(naddr, 0, 0), \ + SPI_MEM_OP_DUMMY(ndummy, 0), \ + SPI_MEM_OP_DATA_IN(len, buf, 0)) + enum spi_nor_option_flags { SNOR_F_HAS_SR_TB = BIT(0), SNOR_F_NO_OP_CHIP_ERASE = BIT(1), @@ -534,6 +541,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_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); int spi_nor_sr_ready(struct spi_nor *nor); int spi_nor_read_cr(struct spi_nor *nor, u8 *cr); |