From nobody Sun Dec 14 19:25:53 2025 Received: from chessie.everett.org (chessie.fmt1.pfcs.com [66.220.13.234]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B76A2155CAE; Fri, 28 Jun 2024 14:04:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.13.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719583465; cv=none; b=hpGVdHrXGa+8jfV6rBfaW6vzwMTLcXBnMMRzCS4kQlBYUjE8Rqk/Ia+jRAUDiLjmoRRxJWBDWbp7EsAKKkkaFEV0ZY5xMnO6cEb4m1UGqktAtXFwKh1V2G1mSA1oMcg1QFPdPb9OS3Wiw4M24ertyhDGjEr/YtLNhldrzvLdZnM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719583465; c=relaxed/simple; bh=aOFbB1UYssZ8v5LPVxLTA42lqnXbomgRjmrdBQDwgdA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=iEIYCWPEUK/pHtCnOaRdVMluVe5Iy6eRTgLN3kw7ON8snalm4OAovQ/s70U0tDvU31IX9dA33yFaPNdJalE1PYt2JcUEMCsO3TcYrgFtbyM6CRcYnpbpI+mDe95iKpp7TT8naFKYMA/S2oQgUhJ9DX/3X4KsyeoKaD7+2V2kOoo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org; spf=pass smtp.mailfrom=nwtime.org; arc=none smtp.client-ip=66.220.13.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=nwtime.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nwtime.org Received: from localhost.localdomain (unknown [31.16.248.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by chessie.everett.org (Postfix) with ESMTPSA id 4W9ccN55gSzMQL9; Fri, 28 Jun 2024 14:04:04 +0000 (UTC) From: Erez Geva To: linux-mtd@lists.infradead.org, Tudor Ambarus , Pratyush Yadav , Michael Walle Cc: linux-kernel@vger.kernel.org, Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , devicetree@vger.kernel.org, Rob Herring , Krzysztof Kozlowski , Conor Dooley , Erez Geva Subject: [PATCH 1/4] Add generic functions for accessing the SPI-NOR chip. Date: Fri, 28 Jun 2024 16:03:25 +0200 Message-Id: <20240628140328.279792-2-erezgeva@nwtime.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240628140328.279792-1-erezgeva@nwtime.org> References: <20240628140328.279792-1-erezgeva@nwtime.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Erez Geva Functions: - Send a opcode - Read a register - Write a register Signed-off-by: Erez Geva --- 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 *n= or, struct spi_mem_op *op, } =20 /** - * spi_nor_write_enable() - Set write enable latch with Write Enable comma= nd. + * _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; =20 if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_WREN_OP; + struct spi_mem_op op =3D SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), + SPI_MEM_OP_NO_ADDR, + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_NO_DATA); =20 spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); =20 ret =3D spi_mem_exec_op(nor->spimem, &op); } else { - ret =3D spi_nor_controller_ops_write_reg(nor, SPINOR_OP_WREN, - NULL, 0); + ret =3D spi_nor_controller_ops_write_reg(nor, opcode, NULL, 0); } =20 - 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 ch= ip. + * @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 =3D _nor_send_cmd(nor, opcode); =20 return ret; } =20 /** - * spi_nor_write_disable() - Send Write Disable instruction to the chip. + * spi_nor_read_reg() - Send instruction without address or data to the ch= ip. * @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; =20 if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_WRDI_OP; + struct spi_mem_op op =3D 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)); =20 spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); =20 ret =3D spi_mem_exec_op(nor->spimem, &op); } else { - ret =3D spi_nor_controller_ops_write_reg(nor, SPINOR_OP_WRDI, - NULL, 0); + ret =3D spi_nor_controller_ops_read_reg(nor, opcode, nor->bouncebuf, len= ); } =20 + return ret; +} + +/* + * spi_nor_write_reg() - Send instruction without address or data to the c= hip. + * @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 =3D 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 =3D spi_mem_exec_op(nor->spimem, &op); + } else { + ret =3D spi_nor_controller_ops_write_reg(nor, opcode, nor->bouncebuf, le= n); + } + + return ret; +} + +/** + * spi_nor_write_enable() - Set write enable latch with Write Enable comma= nd. + * @nor: pointer to 'struct spi_nor'. + * + * Return: 0 on success, -errno otherwise. + */ +int spi_nor_write_enable(struct spi_nor *nor) +{ + int ret; + + ret =3D _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 =3D _nor_send_cmd(nor, SPINOR_OP_WRDI); + if (ret) dev_dbg(nor->dev, "error %d on Write Disable\n", ret); =20 @@ -521,18 +602,8 @@ int spi_nor_set_4byte_addr_mode_en4b_ex4b(struct spi_n= or *nor, bool enable) { int ret; =20 - if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_EN4B_EX4B_OP(enable); - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret =3D spi_mem_exec_op(nor->spimem, &op); - } else { - ret =3D spi_nor_controller_ops_write_reg(nor, - enable ? SPINOR_OP_EN4B : - SPINOR_OP_EX4B, - NULL, 0); - } + ret =3D _nor_send_cmd(nor, enable ? SPINOR_OP_EN4B : + SPINOR_OP_EX4B); =20 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; =20 - if (nor->spimem) { - struct spi_mem_op op =3D SPI_NOR_GBULK_OP; - - spi_nor_spimem_setup_op(nor, &op, nor->reg_proto); - - ret =3D spi_mem_exec_op(nor->spimem, &op); - } else { - ret =3D spi_nor_controller_ops_write_reg(nor, SPINOR_OP_GBULK, - NULL, 0); - } + ret =3D _nor_send_cmd(nor, SPINOR_OP_GBULK); =20 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)) =20 -#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)) =20 -#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)) =20 -#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_grou= ps[]; 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= ); --=20 2.39.2