From: Erez Geva <ErezGeva2@xxxxxxxxx> Functions: - Send an opcode - Read a register - Write a register Signed-off-by: Erez Geva <ErezGeva2@xxxxxxxxx> --- 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