kernel: mtd: spinand: esmt: add support for F50L1G41LC

Backport upstream patch to add support for the ESMT F50L1G41LC flash
chip. It is used in multiple Cudy products manufactured starting
November 2025.

(cherry picked from commit 9424b2b786)
Link: https://github.com/openwrt/openwrt/pull/20963
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Hauke Mehrtens 2025-11-27 21:13:04 +01:00
parent 648fa1b6d3
commit 6ff763e78c
9 changed files with 102 additions and 18 deletions

View file

@ -8,7 +8,7 @@
static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
{
@@ -1352,6 +1353,7 @@ static int spinand_probe(struct spi_mem
@@ -1353,6 +1354,7 @@ static int spinand_probe(struct spi_mem
if (ret)
return ret;
@ -16,7 +16,7 @@
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
goto err_spinand_cleanup;
@@ -1359,6 +1361,7 @@ static int spinand_probe(struct spi_mem
@@ -1360,6 +1362,7 @@ static int spinand_probe(struct spi_mem
return 0;
err_spinand_cleanup:
@ -24,7 +24,7 @@
spinand_cleanup(spinand);
return ret;
@@ -1377,6 +1380,7 @@ static int spinand_remove(struct spi_mem
@@ -1378,6 +1381,7 @@ static int spinand_remove(struct spi_mem
if (ret)
return ret;

View file

@ -0,0 +1,84 @@
From b98994cb9bc24f5c7575c86650f96c384576fdfa Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 17 Nov 2025 02:54:19 +0000
Subject: [PATCH] mtd: spinand: esmt: add support for F50L1G41LC
This adds support for ESMT F50L1G41LC, which appears to be an updated
version of the already supported F50L1G41LB.
Add esmt_8c SPI_NAND manufacturer to account for the newly used vendor
ID with support for the ESMT F50L1G41LC chip.
Link: https://github.com/openwrt/openwrt/pull/15214#issuecomment-3514824435
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
drivers/mtd/nand/spi/core.c | 1 +
drivers/mtd/nand/spi/esmt.c | 24 ++++++++++++++++++++++++
include/linux/mtd/spinand.h | 1 +
3 files changed, 26 insertions(+)
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -942,6 +942,7 @@ static const struct nand_ops spinand_ops
static const struct spinand_manufacturer *spinand_manufacturers[] = {
&alliancememory_spinand_manufacturer,
&ato_spinand_manufacturer,
+ &esmt_8c_spinand_manufacturer,
&esmt_c8_spinand_manufacturer,
&fmsh_spinand_manufacturer,
&foresee_spinand_manufacturer,
--- a/drivers/mtd/nand/spi/esmt.c
+++ b/drivers/mtd/nand/spi/esmt.c
@@ -11,6 +11,7 @@
/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */
#define SPINAND_MFR_ESMT_C8 0xc8
+#define SPINAND_MFR_ESMT_8C 0x8c
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
@@ -102,6 +103,19 @@ static const struct mtd_ooblayout_ops f5
.free = f50l1g41lb_ooblayout_free,
};
+
+static const struct spinand_info esmt_8c_spinand_table[] = {
+ SPINAND_INFO("F50L1G41LC",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x2C),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(1, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)),
+};
+
static const struct spinand_info esmt_c8_spinand_table[] = {
SPINAND_INFO("F50L1G41LB",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01, 0x7f,
@@ -138,6 +152,14 @@ static const struct spinand_info esmt_c8
static const struct spinand_manufacturer_ops esmt_spinand_manuf_ops = {
};
+const struct spinand_manufacturer esmt_8c_spinand_manufacturer = {
+ .id = SPINAND_MFR_ESMT_8C,
+ .name = "ESMT",
+ .chips = esmt_8c_spinand_table,
+ .nchips = ARRAY_SIZE(esmt_8c_spinand_table),
+ .ops = &esmt_spinand_manuf_ops,
+};
+
const struct spinand_manufacturer esmt_c8_spinand_manufacturer = {
.id = SPINAND_MFR_ESMT_C8,
.name = "ESMT",
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -262,6 +262,7 @@ struct spinand_manufacturer {
/* SPI NAND manufacturers */
extern const struct spinand_manufacturer alliancememory_spinand_manufacturer;
extern const struct spinand_manufacturer ato_spinand_manufacturer;
+extern const struct spinand_manufacturer esmt_8c_spinand_manufacturer;
extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
extern const struct spinand_manufacturer fmsh_spinand_manufacturer;
extern const struct spinand_manufacturer foresee_spinand_manufacturer;

View file

@ -53,7 +53,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1291,6 +1291,7 @@ static int spinand_init(struct spinand_d
@@ -1292,6 +1292,7 @@ static int spinand_init(struct spinand_d
/* Propagate ECC information to mtd_info */
mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength;
mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size;

View file

@ -49,9 +49,9 @@ Submitted-by: Daniel Danzberger <daniel@dd-wrt.com>
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -943,6 +943,7 @@ static const struct spinand_manufacturer
&alliancememory_spinand_manufacturer,
@@ -944,6 +944,7 @@ static const struct spinand_manufacturer
&ato_spinand_manufacturer,
&esmt_8c_spinand_manufacturer,
&esmt_c8_spinand_manufacturer,
+ &etron_spinand_manufacturer,
&fmsh_spinand_manufacturer,
@ -160,9 +160,9 @@ Submitted-by: Daniel Danzberger <daniel@dd-wrt.com>
+};
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -263,6 +263,7 @@ struct spinand_manufacturer {
extern const struct spinand_manufacturer alliancememory_spinand_manufacturer;
@@ -264,6 +264,7 @@ extern const struct spinand_manufacturer
extern const struct spinand_manufacturer ato_spinand_manufacturer;
extern const struct spinand_manufacturer esmt_8c_spinand_manufacturer;
extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
+extern const struct spinand_manufacturer etron_spinand_manufacturer;
extern const struct spinand_manufacturer fmsh_spinand_manufacturer;

View file

@ -8,7 +8,7 @@
static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
{
@@ -1352,6 +1353,7 @@ static int spinand_probe(struct spi_mem
@@ -1353,6 +1354,7 @@ static int spinand_probe(struct spi_mem
if (ret)
return ret;
@ -16,7 +16,7 @@
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
goto err_spinand_cleanup;
@@ -1359,6 +1361,7 @@ static int spinand_probe(struct spi_mem
@@ -1360,6 +1362,7 @@ static int spinand_probe(struct spi_mem
return 0;
err_spinand_cleanup:
@ -24,7 +24,7 @@
spinand_cleanup(spinand);
return ret;
@@ -1377,6 +1380,7 @@ static int spinand_remove(struct spi_mem
@@ -1378,6 +1381,7 @@ static int spinand_remove(struct spi_mem
if (ret)
return ret;

View file

@ -24,7 +24,7 @@ Signed-off-by: Davide Fioravanti <pantanastyle@gmail.com>
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -946,6 +946,7 @@ static const struct spinand_manufacturer
@@ -947,6 +947,7 @@ static const struct spinand_manufacturer
&esmt_c8_spinand_manufacturer,
&etron_spinand_manufacturer,
&fmsh_spinand_manufacturer,
@ -113,7 +113,7 @@ Signed-off-by: Davide Fioravanti <pantanastyle@gmail.com>
+};
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -265,6 +265,7 @@ extern const struct spinand_manufacturer
@@ -266,6 +266,7 @@ extern const struct spinand_manufacturer
extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
extern const struct spinand_manufacturer etron_spinand_manufacturer;
extern const struct spinand_manufacturer fmsh_spinand_manufacturer;

View file

@ -11,7 +11,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -984,6 +984,56 @@ static int spinand_manufacturer_match(st
@@ -985,6 +985,56 @@ static int spinand_manufacturer_match(st
return -ENOTSUPP;
}
@ -68,7 +68,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
static int spinand_id_detect(struct spinand_device *spinand)
{
u8 *id = spinand->id.data;
@@ -1234,6 +1284,10 @@ static int spinand_init(struct spinand_d
@@ -1235,6 +1285,10 @@ static int spinand_init(struct spinand_d
if (!spinand->scratchbuf)
return -ENOMEM;

View file

@ -12,7 +12,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1025,7 +1025,10 @@ int spinand_cal_read(void *priv, u32 *ad
@@ -1026,7 +1026,10 @@ int spinand_cal_read(void *priv, u32 *ad
if (ret)
return ret;

View file

@ -29,7 +29,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1446,6 +1446,7 @@ static int spinand_remove(struct spi_mem
@@ -1447,6 +1447,7 @@ static int spinand_remove(struct spi_mem
static const struct spi_device_id spinand_ids[] = {
{ .name = "spi-nand" },
@ -37,7 +37,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(spi, spinand_ids);
@@ -1453,6 +1454,7 @@ MODULE_DEVICE_TABLE(spi, spinand_ids);
@@ -1454,6 +1455,7 @@ MODULE_DEVICE_TABLE(spi, spinand_ids);
#ifdef CONFIG_OF
static const struct of_device_id spinand_of_ids[] = {
{ .compatible = "spi-nand" },