Skip to content

Commit f6dffe2

Browse files
csharper2005miquelraynal
authored andcommitted
mtd: spinand: add support for FudanMicro FM25S01BI3
Add support for FudanMicro FM25S01BI3 SPI NAND. Link: https://www.fmsh.com/nvm/FM25S01BI3_ds_eng.pdf Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
1 parent a3623e1 commit f6dffe2

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

drivers/mtd/nand/spi/fmsh.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
#include <linux/kernel.h>
1010
#include <linux/mtd/spinand.h>
1111

12+
#define FM25S01BI3_STATUS_ECC_MASK (7 << 4)
13+
#define FM25S01BI3_STATUS_ECC_NO_BITFLIPS (0 << 4)
14+
#define FM25S01BI3_STATUS_ECC_1_3_BITFLIPS (1 << 4)
15+
#define FM25S01BI3_STATUS_ECC_UNCOR_ERROR (2 << 4)
16+
#define FM25S01BI3_STATUS_ECC_4_6_BITFLIPS (3 << 4)
17+
#define FM25S01BI3_STATUS_ECC_7_8_BITFLIPS (5 << 4)
18+
1219
#define SPINAND_MFR_FMSH 0xA1
1320

1421
static SPINAND_OP_VARIANTS(read_cache_variants,
@@ -45,11 +52,66 @@ static int fm25s01a_ooblayout_free(struct mtd_info *mtd, int section,
4552
return 0;
4653
}
4754

55+
static int fm25s01bi3_ecc_get_status(struct spinand_device *spinand,
56+
u8 status)
57+
{
58+
switch (status & FM25S01BI3_STATUS_ECC_MASK) {
59+
case FM25S01BI3_STATUS_ECC_NO_BITFLIPS:
60+
return 0;
61+
62+
case FM25S01BI3_STATUS_ECC_UNCOR_ERROR:
63+
return -EBADMSG;
64+
65+
case FM25S01BI3_STATUS_ECC_1_3_BITFLIPS:
66+
return 3;
67+
68+
case FM25S01BI3_STATUS_ECC_4_6_BITFLIPS:
69+
return 6;
70+
71+
case FM25S01BI3_STATUS_ECC_7_8_BITFLIPS:
72+
return 8;
73+
74+
default:
75+
break;
76+
}
77+
78+
return -EINVAL;
79+
}
80+
81+
static int fm25s01bi3_ooblayout_ecc(struct mtd_info *mtd, int section,
82+
struct mtd_oob_region *region)
83+
{
84+
if (section)
85+
return -ERANGE;
86+
87+
region->offset = 64;
88+
region->length = 64;
89+
90+
return 0;
91+
}
92+
93+
static int fm25s01bi3_ooblayout_free(struct mtd_info *mtd, int section,
94+
struct mtd_oob_region *region)
95+
{
96+
if (section > 3)
97+
return -ERANGE;
98+
99+
region->offset = (16 * section) + 4;
100+
region->length = 12;
101+
102+
return 0;
103+
}
104+
48105
static const struct mtd_ooblayout_ops fm25s01a_ooblayout = {
49106
.ecc = fm25s01a_ooblayout_ecc,
50107
.free = fm25s01a_ooblayout_free,
51108
};
52109

110+
static const struct mtd_ooblayout_ops fm25s01bi3_ooblayout = {
111+
.ecc = fm25s01bi3_ooblayout_ecc,
112+
.free = fm25s01bi3_ooblayout_free,
113+
};
114+
53115
static const struct spinand_info fmsh_spinand_table[] = {
54116
SPINAND_INFO("FM25S01A",
55117
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
@@ -60,6 +122,16 @@ static const struct spinand_info fmsh_spinand_table[] = {
60122
&update_cache_variants),
61123
SPINAND_HAS_QE_BIT,
62124
SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)),
125+
SPINAND_INFO("FM25S01BI3",
126+
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xd4),
127+
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
128+
NAND_ECCREQ(8, 512),
129+
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
130+
&write_cache_variants,
131+
&update_cache_variants),
132+
SPINAND_HAS_QE_BIT,
133+
SPINAND_ECCINFO(&fm25s01bi3_ooblayout,
134+
fm25s01bi3_ecc_get_status)),
63135
};
64136

65137
static const struct spinand_manufacturer_ops fmsh_spinand_manuf_ops = {

0 commit comments

Comments
 (0)