[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240629103914.161530-2-erezgeva@nwtime.org>
Date: Sat, 29 Jun 2024 12:39:10 +0200
From: Erez Geva <erezgeva@...ime.org>
To: linux-mtd@...ts.infradead.org,
Tudor Ambarus <tudor.ambarus@...aro.org>,
Pratyush Yadav <pratyush@...nel.org>,
Michael Walle <mwalle@...nel.org>
Cc: linux-kernel@...r.kernel.org,
Miquel Raynal <miquel.raynal@...tlin.com>,
Richard Weinberger <richard@....at>,
Vignesh Raghavendra <vigneshr@...com>,
devicetree@...r.kernel.org,
Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>,
Erez Geva <ErezGeva2@...il.com>
Subject: [PATCH v2 1/4] Add generic functions for accessing the SPI-NOR chip.
From: Erez Geva <ErezGeva2@...il.com>
Functions:
- Send an opcode
- Read a register
- Write a register
Signed-off-by: Erez Geva <ErezGeva2@...il.com>
---
drivers/mtd/spi-nor/core.c | 130 +++++++++++++++++++++++++++----------
drivers/mtd/spi-nor/core.h | 27 +-------
2 files changed, 99 insertions(+), 58 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 028514c6996f..0f267da339a4 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -354,53 +354,134 @@ int spi_nor_write_any_volatile_reg(struct spi_nor *nor, struct spi_mem_op *op,
}
/**
- * spi_nor_write_enable() - Set write enable latch with Write Enable command.
+ * _nor_send_cmd() - Send instruction without address or data to the chip.
* @nor: pointer to 'struct spi_nor'.
+ * @opcode: Command to send
*
* Return: 0 on success, -errno otherwise.
*/
-int spi_nor_write_enable(struct spi_nor *nor)
+static inline int _nor_send_cmd(struct spi_nor *nor, u8 opcode)
{
int ret;
if (nor->spimem) {
- struct spi_mem_op op = SPI_NOR_WREN_OP;
+ struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0),
+ SPI_MEM_OP_NO_ADDR,
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_NO_DATA);
spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
ret = spi_mem_exec_op(nor->spimem, &op);
} else {
- ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_WREN,
- NULL, 0);
+ ret = spi_nor_controller_ops_write_reg(nor, opcode, NULL, 0);
}
- if (ret)
- dev_dbg(nor->dev, "error %d on Write Enable\n", ret);
+ return ret;
+}
+
+/**
+ * spi_nor_send_cmd() - Send instruction without address or data to the chip.
+ * @nor: pointer to 'struct spi_nor'.
+ * @opcode: Command to send
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int spi_nor_send_cmd(struct spi_nor *nor, u8 opcode)
+{
+ int ret;
+
+ ret = _nor_send_cmd(nor, opcode);
return ret;
}
/**
- * spi_nor_write_disable() - Send Write Disable instruction to the chip.
+ * spi_nor_read_reg() - Send instruction without address or data to the chip.
* @nor: pointer to 'struct spi_nor'.
+ * @opcode: Command to send
+ * @len: register value length
*
* Return: 0 on success, -errno otherwise.
*/
-int spi_nor_write_disable(struct spi_nor *nor)
+int spi_nor_read_reg(struct spi_nor *nor, u8 opcode, size_t len)
{
int ret;
if (nor->spimem) {
- struct spi_mem_op op = SPI_NOR_WRDI_OP;
+ struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0),
+ SPI_MEM_OP_NO_ADDR,
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_IN(len, nor->bouncebuf, 0));
spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
ret = spi_mem_exec_op(nor->spimem, &op);
} else {
- ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_WRDI,
- NULL, 0);
+ ret = spi_nor_controller_ops_read_reg(nor, opcode, nor->bouncebuf, len);
}
+ return ret;
+}
+
+/*
+ * spi_nor_write_reg() - Send instruction without address or data to the chip.
+ * @nor: pointer to 'struct spi_nor'.
+ * @opcode: Command to send
+ * @len: register value length
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, size_t len)
+{
+ int ret;
+
+ if (nor->spimem) {
+ struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0),
+ SPI_MEM_OP_NO_ADDR,
+ SPI_MEM_OP_NO_DUMMY,
+ SPI_MEM_OP_DATA_OUT(len, nor->bouncebuf, 0));
+
+ spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+
+ ret = spi_mem_exec_op(nor->spimem, &op);
+ } else {
+ ret = spi_nor_controller_ops_write_reg(nor, opcode, nor->bouncebuf, len);
+ }
+
+ return ret;
+}
+
+/**
+ * spi_nor_write_enable() - Set write enable latch with Write Enable command.
+ * @nor: pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int spi_nor_write_enable(struct spi_nor *nor)
+{
+ int ret;
+
+ ret = _nor_send_cmd(nor, SPINOR_OP_WREN);
+
+ if (ret)
+ dev_dbg(nor->dev, "error %d on Write Enable\n", ret);
+
+ return ret;
+}
+
+/**
+ * spi_nor_write_disable() - Send Write Disable instruction to the chip.
+ * @nor: pointer to 'struct spi_nor'.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int spi_nor_write_disable(struct spi_nor *nor)
+{
+ int ret;
+
+ ret = _nor_send_cmd(nor, SPINOR_OP_WRDI);
+
if (ret)
dev_dbg(nor->dev, "error %d on Write Disable\n", ret);
@@ -521,18 +602,8 @@ int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_nor *nor, bool enable)
{
int ret;
- if (nor->spimem) {
- struct spi_mem_op op = SPI_NOR_EN4B_EX4B_OP(enable);
-
- spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-
- ret = spi_mem_exec_op(nor->spimem, &op);
- } else {
- ret = spi_nor_controller_ops_write_reg(nor,
- enable ? SPINOR_OP_EN4B :
- SPINOR_OP_EX4B,
- NULL, 0);
- }
+ ret = _nor_send_cmd(nor, enable ? SPINOR_OP_EN4B :
+ SPINOR_OP_EX4B);
if (ret)
dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret);
@@ -765,16 +836,7 @@ int spi_nor_global_block_unlock(struct spi_nor *nor)
if (ret)
return ret;
- if (nor->spimem) {
- struct spi_mem_op op = SPI_NOR_GBULK_OP;
-
- spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-
- ret = spi_mem_exec_op(nor->spimem, &op);
- } else {
- ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_GBULK,
- NULL, 0);
- }
+ ret = _nor_send_cmd(nor, SPINOR_OP_GBULK);
if (ret) {
dev_dbg(nor->dev, "error %d on Global Block Unlock\n", ret);
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 442786685515..df456a713d92 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -25,18 +25,6 @@
SPI_MEM_OP_DUMMY(ndummy, 0), \
SPI_MEM_OP_DATA_IN(len, buf, 0))
-#define SPI_NOR_WREN_OP \
- SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 0), \
- SPI_MEM_OP_NO_ADDR, \
- SPI_MEM_OP_NO_DUMMY, \
- SPI_MEM_OP_NO_DATA)
-
-#define SPI_NOR_WRDI_OP \
- SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 0), \
- SPI_MEM_OP_NO_ADDR, \
- SPI_MEM_OP_NO_DUMMY, \
- SPI_MEM_OP_NO_DATA)
-
#define SPI_NOR_RDSR_OP(buf) \
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 0), \
SPI_MEM_OP_NO_ADDR, \
@@ -67,24 +55,12 @@
SPI_MEM_OP_NO_DUMMY, \
SPI_MEM_OP_DATA_IN(1, buf, 0))
-#define SPI_NOR_EN4B_EX4B_OP(enable) \
- SPI_MEM_OP(SPI_MEM_OP_CMD(enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B, 0), \
- SPI_MEM_OP_NO_ADDR, \
- SPI_MEM_OP_NO_DUMMY, \
- SPI_MEM_OP_NO_DATA)
-
#define SPI_NOR_BRWR_OP(buf) \
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_BRWR, 0), \
SPI_MEM_OP_NO_ADDR, \
SPI_MEM_OP_NO_DUMMY, \
SPI_MEM_OP_DATA_OUT(1, buf, 0))
-#define SPI_NOR_GBULK_OP \
- SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_GBULK, 0), \
- SPI_MEM_OP_NO_ADDR, \
- SPI_MEM_OP_NO_DUMMY, \
- SPI_MEM_OP_NO_DATA)
-
#define SPI_NOR_DIE_ERASE_OP(opcode, addr_nbytes, addr, dice) \
SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \
SPI_MEM_OP_ADDR(dice ? addr_nbytes : 0, addr, 0), \
@@ -611,6 +587,9 @@ extern const struct attribute_group *spi_nor_sysfs_groups[];
void spi_nor_spimem_setup_op(const struct spi_nor *nor,
struct spi_mem_op *op,
const enum spi_nor_protocol proto);
+int spi_nor_send_cmd(struct spi_nor *nor, u8 opcode);
+int spi_nor_read_reg(struct spi_nor *nor, u8 opcode, size_t len);
+int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, size_t len);
int spi_nor_write_enable(struct spi_nor *nor);
int spi_nor_write_disable(struct spi_nor *nor);
int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_nor *nor, bool enable);
--
2.39.2
Powered by blists - more mailing lists