aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/raw/Makefile1
-rw-r--r--drivers/mtd/nand/raw/internals.h1
-rw-r--r--drivers/mtd/nand/raw/nand_esmt.c47
-rw-r--r--drivers/mtd/nand/raw/nand_ids.c2
4 files changed, 50 insertions, 1 deletions
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index be2c17863ee5..57159b349054 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -61,6 +61,7 @@ nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
nand-objs += nand_onfi.o
nand-objs += nand_jedec.o
nand-objs += nand_amd.o
+nand-objs += nand_esmt.o
nand-objs += nand_hynix.o
nand-objs += nand_macronix.o
nand-objs += nand_micron.o
diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index f624b7b80413..04c2cf74eff3 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -67,6 +67,7 @@ struct nand_manufacturer {
extern struct nand_flash_dev nand_flash_ids[];
extern const struct nand_manufacturer_ops amd_nand_manuf_ops;
+extern const struct nand_manufacturer_ops esmt_nand_manuf_ops;
extern const struct nand_manufacturer_ops hynix_nand_manuf_ops;
extern const struct nand_manufacturer_ops macronix_nand_manuf_ops;
extern const struct nand_manufacturer_ops micron_nand_manuf_ops;
diff --git a/drivers/mtd/nand/raw/nand_esmt.c b/drivers/mtd/nand/raw/nand_esmt.c
new file mode 100644
index 000000000000..96f039a83bc8
--- /dev/null
+++ b/drivers/mtd/nand/raw/nand_esmt.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Toradex AG
+ *
+ * Author: Marcel Ziswiler <marcel.ziswiler@toradex.com>
+ */
+
+#include <linux/mtd/rawnand.h>
+#include "internals.h"
+
+static void esmt_nand_decode_id(struct nand_chip *chip)
+{
+ nand_decode_ext_id(chip);
+
+ /* Extract ECC requirements from 5th id byte. */
+ if (chip->id.len >= 5 && nand_is_slc(chip)) {
+ chip->ecc_step_ds = 512;
+ switch (chip->id.data[4] & 0x3) {
+ case 0x0:
+ chip->ecc_strength_ds = 4;
+ break;
+ case 0x1:
+ chip->ecc_strength_ds = 2;
+ break;
+ case 0x2:
+ chip->ecc_strength_ds = 1;
+ break;
+ default:
+ WARN(1, "Could not get ECC info");
+ chip->ecc_step_ds = 0;
+ break;
+ }
+ }
+}
+
+static int esmt_nand_init(struct nand_chip *chip)
+{
+ if (nand_is_slc(chip))
+ chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+
+ return 0;
+}
+
+const struct nand_manufacturer_ops esmt_nand_manuf_ops = {
+ .detect = esmt_nand_decode_id,
+ .init = esmt_nand_init,
+};
diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c
index fd0a7f711100..ea5a342cd91e 100644
--- a/drivers/mtd/nand/raw/nand_ids.c
+++ b/drivers/mtd/nand/raw/nand_ids.c
@@ -174,7 +174,7 @@ static const struct nand_manufacturer nand_manufacturers[] = {
{NAND_MFR_AMD, "AMD/Spansion", &amd_nand_manuf_ops},
{NAND_MFR_ATO, "ATO"},
{NAND_MFR_EON, "Eon"},
- {NAND_MFR_ESMT, "ESMT"},
+ {NAND_MFR_ESMT, "ESMT", &esmt_nand_manuf_ops},
{NAND_MFR_FUJITSU, "Fujitsu"},
{NAND_MFR_HYNIX, "Hynix", &hynix_nand_manuf_ops},
{NAND_MFR_INTEL, "Intel"},