@@ -247,6 +247,54 @@ ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, u8 *buf)
return nor->controller_ops->read(nor, from, len, buf);
}
+/**
+ * spi_nor_alt_read() - read data from flash memory with alternative opcode,
+ * number of address bytes, and dummy cycles.
+ * @nor: pointer to 'struct spi_nor'
+ * @from: offset to read from
+ * @len: number of bytes to read
+ * @buf: pointer to dst buffer
+ * @read_opcode: read opcode to issue
+ * @addr_nbytes: number of address bytes to send
+ * @read_dummy: number of dummy cycles needed to read
+ *
+ * Return: 0 on success, -errno otherwise
+ */
+int spi_nor_alt_read(struct spi_nor *nor, u32 addr, size_t len, u8 *buf,
+ u8 read_opcode, u8 addr_nbytes, u8 read_dummy)
+{
+ u8 bak_read_opcode = nor->read_opcode;
+ u8 bak_addr_nbytes = nor->addr_nbytes;
+ u8 bak_read_dummy = nor->read_dummy;
+ ssize_t ret;
+
+ nor->read_opcode = read_opcode;
+ nor->addr_nbytes = addr_nbytes;
+ nor->read_dummy = read_dummy;
+
+ while (len) {
+ ret = spi_nor_read_data(nor, addr, len, buf);
+ if (ret < 0)
+ goto out;
+ if (!ret || ret > len) {
+ ret = -EIO;
+ goto out;
+ }
+
+ buf += ret;
+ addr += ret;
+ len -= ret;
+ }
+ ret = 0;
+
+out:
+ nor->read_opcode = bak_read_opcode;
+ nor->addr_nbytes = bak_addr_nbytes;
+ nor->read_dummy = bak_read_dummy;
+
+ return ret;
+}
+
/**
* spi_nor_spimem_write_data() - write data to flash memory via
* spi-mem
@@ -656,6 +656,8 @@ ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len,
u8 *buf);
ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
const u8 *buf);
+int spi_nor_alt_read(struct spi_nor *nor, u32 addr, size_t len, u8 *buf,
+ u8 read_opcode, u8 addr_nbytes, u8 read_dummy);
int spi_nor_read_any_reg(struct spi_nor *nor, struct spi_mem_op *op,
enum spi_nor_protocol proto);
int spi_nor_write_any_volatile_reg(struct spi_nor *nor, struct spi_mem_op *op,