From: Thomas Koeller <thomas.koeller@baslerweb.com>
To: linux-mtd@lists.infradead.org
Cc: linux-mips@linux-mips.org
Subject: [PATCH] eXcite nand flash driver
Date: Thu, 8 Feb 2007 01:57:25 +0100 [thread overview]
Message-ID: <200702080157.25432.thomas.koeller@baslerweb.com> (raw)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 10036 bytes --]
This is a nand flash driver for the eXcite series of intelligent
cameras manufactured by Basler Vision Technologies AG.
Signed-off-by: Thomas Koeller <thomas.koeller@baslerweb.com>
---
drivers/mtd/nand/Kconfig | 18 +++-
drivers/mtd/nand/Makefile | 1 +
drivers/mtd/nand/excite_nandflash.c | 259
+++++++++++++++++++++++++++++++++++
3 files changed, 277 insertions(+), 1 deletions(-)
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 358f55a..5b50396 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -216,10 +216,26 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
Even if you leave this disabled, you can enable BBT writes at module
load time (assuming you build diskonchip as a module) with the module
parameter "inftl_bbt_write=1".
-
+
config MTD_NAND_SHARPSL
tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
depends on MTD_NAND && ARCH_PXA
+
+config MTD_NAND_BASLER_EXCITE
+ tristate "Support for NAND Flash on Basler eXcite"
+ depends on MTD_NAND && BASLER_EXCITE
+ help
+ This enables the driver for the NAND flash device found on the
+ Basler eXcite Smart Camera. If built as a module, the driver
+ will be named "excite_nandflash.ko".
+
+config MTD_NAND_BASLER_EXCITE
+ tristate "Support for NAND Flash on Basler eXcite"
+ depends on MTD_NAND && BASLER_EXCITE
+ help
+ This enables the driver for the NAND flash device found on the
+ Basler eXcite Smart Camera. If built as a module, the driver
+ will be named "excite_nandflash.ko".
config MTD_NAND_CAFE
tristate "NAND support for OLPC CAFÉ chip"
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index f7a53f0..80f1dfc 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MTD_NAND_NANDSIM) += nands
obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o
+obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
nand-objs := nand_base.o nand_bbt.o
cafe_nand-objs := cafe.o cafe_ecc.o
diff --git a/drivers/mtd/nand/excite_nandflash.c
b/drivers/mtd/nand/excite_nandflash.c
new file mode 100644
index 0000000..d683659
--- /dev/null
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -0,0 +1,259 @@
+/*
+* Copyright (C) 2005 - 2007 by Basler Vision Technologies AG
+* Author: Thomas Koeller <thomas.koeller.qbaslerweb.com>
+* Original code by Thies Moeller <thies.moeller@baslerweb.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/rm9k-ocd.h>
+
+#include <excite_nandflash.h>
+
+#define EXCITE_NANDFLASH_VERSION "0.1"
+
+/* I/O register offsets */
+#define EXCITE_NANDFLASH_DATA_BYTE 0x00
+#define EXCITE_NANDFLASH_STATUS_BYTE 0x0c
+#define EXCITE_NANDFLASH_ADDR_BYTE 0x10
+#define EXCITE_NANDFLASH_CMD_BYTE 0x14
+
+#define io_readb(__a__) __raw_readb((__a__))
+#define io_writeb(__v__, __a__) __raw_writeb((__v__), (__a__))
+
+typedef void __iomem *io_reg_t;
+
+/* prefix for debug output */
+static const char module_id[] = "excite_nandflash";
+
+/*
+ * partition definition
+ */
+static const struct mtd_partition partition_info[] = {
+ {
+ .name = "eXcite RootFS",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL
+ }
+};
+
+static inline const struct resource *excite_nand_get_resource
+ (struct platform_device *d, unsigned long flags, const char *basename) {
+ const char fmt[] = "%s_%u";
+ char buf[80];
+
+ if (unlikely
+ (snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf))
+ return NULL;
+ return platform_get_resource_byname(d, flags, buf);
+}
+
+static inline io_reg_t
+excite_nand_map_regs(struct platform_device *d, const char *basename)
+{
+ void *result = NULL;
+ const struct resource *const r =
+ excite_nand_get_resource(d, IORESOURCE_MEM, basename);
+ if (likely(r))
+ result = ioremap_nocache(r->start, r->end + 1 - r->start);
+ return result;
+}
+
+/* controller and mtd information */
+struct excite_nand_drvdata {
+ struct mtd_info board_mtd;
+ struct nand_chip board_chip;
+ io_reg_t regs;
+};
+
+/* command and control functions */
+static void excite_nand_control(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ io_reg_t regs =
+ container_of(mtd, struct excite_nand_drvdata, board_mtd)->regs;
+ static void __iomem *tgt = NULL;
+
+ switch (ctrl) {
+ case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
+ tgt = regs + EXCITE_NANDFLASH_CMD_BYTE;
+ break;
+ case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
+ tgt = regs + EXCITE_NANDFLASH_ADDR_BYTE;
+ break;
+ case NAND_CTRL_CHANGE | NAND_NCE:
+ tgt = regs + EXCITE_NANDFLASH_DATA_BYTE;
+ break;
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ io_writeb(cmd, tgt);
+}
+
+/* excite_nand_devready()
+ *
+ * returns 0 if the nand is busy, 1 if it is ready
+ */
+static int excite_nand_devready(struct mtd_info *mtd)
+{
+ struct excite_nand_drvdata * const drvdata =
+ container_of(mtd, struct excite_nand_drvdata, board_mtd);
+ return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS_BYTE);
+}
+
+/* excite_nand_remove
+ *
+ * called by device layer to remove the driver
+ * the binding to the mtd and all allocated
+ * resources are released
+ */
+static int __exit excite_nand_remove(struct device *dev)
+{
+ struct excite_nand_drvdata * const this = dev_get_drvdata(dev);
+
+ dev_set_drvdata(dev, NULL);
+
+ if (unlikely(!this)) {
+ printk(KERN_ERR "%s: called %s without private data!!",
+ module_id, __func__);
+ return -EINVAL;
+ }
+
+ /* first thing we need to do is release our mtd
+ * then go through freeing the resource used
+ */
+ nand_release(&this->board_mtd);
+
+ /* free the common resources */
+ if (likely(this->regs)) {
+ iounmap(this->regs);
+ this->regs = NULL;
+ }
+
+ kfree(this);
+
+ DEBUG(MTD_DEBUG_LEVEL1, "%s: removed\n", module_id);
+ return 0;
+}
+
+/* excite_nand_probe
+ *
+ * called by device layer when it finds a device matching
+ * one our driver can handled. This code checks to see if
+ * it can allocate all necessary resources then calls the
+ * nand layer to look for devices
+*/
+static int __init excite_nand_probe(struct device *dev)
+{
+ struct platform_device * const pdev = to_platform_device(dev);
+
+ struct excite_nand_drvdata *drvdata; /* private driver data */
+ struct nand_chip *board_chip; /* private flash chip data */
+ struct mtd_info *board_mtd; /* mtd info for this board */
+ int scan_res;
+
+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+ if (unlikely(!drvdata)) {
+ printk(KERN_ERR "%s: no memory for drvdata\n",
+ module_id);
+ return -ENOMEM;
+ }
+
+ /* bind private data into driver */
+ dev_set_drvdata(dev, drvdata);
+
+ /* allocate and map the resource */
+ drvdata->regs =
+ excite_nand_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS);
+
+ if (unlikely(!drvdata->regs)) {
+ printk(KERN_ERR "%s: cannot reserve register region\n",
+ module_id);
+ kfree(drvdata);
+ return -ENXIO;
+ }
+
+ /* initialise our chip */
+ board_chip = &drvdata->board_chip;
+ board_chip->IO_ADDR_R = board_chip->IO_ADDR_W =
+ drvdata->regs + EXCITE_NANDFLASH_DATA_BYTE;
+ board_chip->cmd_ctrl = excite_nand_control;
+ board_chip->dev_ready = excite_nand_devready;
+ board_chip->chip_delay = 25;
+ board_chip->ecc.mode = NAND_ECC_SOFT;
+
+ /* link chip to mtd */
+ board_mtd = &drvdata->board_mtd;
+ board_mtd->priv = board_chip;
+
+ DEBUG(MTD_DEBUG_LEVEL2, "%s: device scan\n", module_id);
+ scan_res = nand_scan(&drvdata->board_mtd, 1);
+
+ if (likely(!scan_res)) {
+ DEBUG(MTD_DEBUG_LEVEL2, "%s: register partitions\n", module_id);
+ add_mtd_partitions(&drvdata->board_mtd, partition_info,
+ sizeof partition_info / sizeof partition_info[0]);
+ } else {
+ iounmap(drvdata->regs);
+ kfree(drvdata);
+ printk(KERN_ERR "%s: device scan failed\n", module_id);
+ return -EIO;
+ }
+ return 0;
+}
+
+static struct device_driver excite_nand_driver = {
+ .name = "excite_nand",
+ .bus = &platform_bus_type,
+ .probe = excite_nand_probe,
+ .remove = __exit_p(excite_nand_remove)
+};
+
+static int __init excite_nand_init(void)
+{
+ pr_info("Basler eXcite nand flash driver Version "
+ EXCITE_NANDFLASH_VERSION "\n");
+ return driver_register(&excite_nand_driver);
+}
+
+static void __exit excite_nand_exit(void)
+{
+ driver_unregister(&excite_nand_driver);
+}
+
+module_init(excite_nand_init);
+module_exit(excite_nand_exit);
+
+MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
+MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(EXCITE_NANDFLASH_VERSION)
--
1.4.3
next reply other threads:[~2007-02-08 1:11 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-08 0:57 Thomas Koeller [this message]
2007-02-08 8:20 ` [PATCH] eXcite nand flash driver Ulrich Eckhardt
2007-02-08 10:20 ` Thomas Koeller
2007-02-08 13:50 ` Josh Boyer
2007-02-08 13:50 ` Josh Boyer
2007-02-08 13:55 ` Artem Bityutskiy
2007-02-08 13:55 ` Artem Bityutskiy
2007-02-08 15:48 ` Thomas Gleixner
2007-02-08 15:48 ` Thomas Gleixner
2007-02-10 10:22 ` Thomas Koeller
2007-02-10 10:22 ` Thomas Koeller
2007-02-11 15:44 ` Thomas Gleixner
2007-02-11 15:44 ` Thomas Gleixner
-- strict thread matches above, loose matches on Subject: below --
2007-02-10 10:21 Thomas Koeller
2007-02-11 15:50 ` Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200702080157.25432.thomas.koeller@baslerweb.com \
--to=thomas.koeller@baslerweb.com \
--cc=linux-mips@linux-mips.org \
--cc=linux-mtd@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.