@@ -27,12 +27,13 @@ struct m25p {
u8 command[MAX_CMD_SIZE];
};
-static void m25p_addr2cmd(u32 addr, u8 *cmd)
+static void m25p_addr2cmd(struct spi_nor *nor, unsigned int addr, u8 *cmd)
{
- /* cmd[0] is actual command */
- cmd[1] = addr >> 16;
- cmd[2] = addr >> 8;
- cmd[3] = addr >> 0;
+ /* opcode is in cmd[0] */
+ cmd[1] = addr >> (nor->addr_width * 8 - 8);
+ cmd[2] = addr >> (nor->addr_width * 8 - 16);
+ cmd[3] = addr >> (nor->addr_width * 8 - 24);
+ cmd[4] = addr >> (nor->addr_width * 8 - 32);
}
static int m25p80_read_reg(struct spi_nor *nor, u8 cmd, u8 *val, int len)
@@ -136,7 +137,7 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,
}
flash->command[0] = nor->read_opcode;
- m25p_addr2cmd(from, flash->command);
+ m25p_addr2cmd(nor, from, flash->command);
if (nor->flags & SNOR_F_U_PAGE)
spi->flags |= SPI_XFER_U_PAGE;
@@ -171,7 +172,7 @@ static int m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
cmd_sz = 1;
flash->command[0] = nor->program_opcode;
- m25p_addr2cmd(to, flash->command);
+ m25p_addr2cmd(nor, to, flash->command);
if (nor->flags & SNOR_F_U_PAGE)
spi->flags |= SPI_XFER_U_PAGE;
@@ -204,7 +205,7 @@ static int m25p80_erase(struct spi_nor *nor, loff_t offset)
}
flash->command[0] = nor->erase_opcode;
- m25p_addr2cmd(offset, flash->command);
+ m25p_addr2cmd(nor, offset, flash->command);
if (nor->flags & SNOR_F_U_PAGE)
spi->flags |= SPI_XFER_U_PAGE;
@@ -1032,6 +1032,11 @@ int spi_nor_scan(struct spi_nor *nor)
}
}
+ if (info->addr_width)
+ nor->addr_width = info->addr_width;
+ else
+ nor->addr_width = 3;
+
/* read_dummy: dummy byte is determined based on the
* dummy cycles of a particular command.
* Fast commands - read_dummy = dummy_cycles/8
@@ -171,6 +171,7 @@ extern const struct spi_nor_info spi_nor_ids[];
* @mtd: point to a mtd_info structure
* @name: name of the SPI NOR device
* @page_size: the page size of the SPI NOR
+ * @addr_width: number of address bytes
* @erase_opcode: the opcode for erasing a sector
* @read_opcode: the read opcode
* @read_dummy: the dummy bytes needed by the read operation
@@ -202,6 +203,7 @@ struct spi_nor {
struct mtd_info *mtd;
const char *name;
u32 page_size;
+ u8 addr_width;
u8 erase_opcode;
u8 read_opcode;
u8 read_dummy;
addr_width is required to configure the flash with 3 and 4 byte addressing, more features will add in future patches. Cc: Simon Glass <sjg@chromium.org> Cc: Bin Meng <bmeng.cn@gmail.com> Cc: Mugunthan V N <mugunthanvnm@ti.com> Cc: Michal Simek <michal.simek@xilinx.com> Cc: Siva Durga Prasad Paladugu <sivadur@xilinx.com> Signed-off-by: Jagan Teki <jteki@openedev.com> --- drivers/mtd/spi-nor/m25p80.c | 17 +++++++++-------- drivers/mtd/spi-nor/spi-nor.c | 5 +++++ include/linux/mtd/spi-nor.h | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-)