/*
* Copyright © 2012 Mike Dunn <mikedunn@newsguy.com>
*
* mtd nand driver for M-Systems DiskOnChip G4
*
* 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.
*
* Tested on the Palm Treo 680. The G4 is also present on Toshiba Portege, Asus
* P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others.
* Should work on these as well. Let me know!
*
* TODO:
*
* Mechanism for management of password-protected areas
*
* Hamming ecc when reading oob only
*
* According to the M-Sys documentation, this device is also available in a
* "dual-die" configuration having a 256MB capacity, but no mechanism for
* detecting this variant is documented. Currently this driver assumes 128MB
* capacity.
*
* Support for multiple cascaded devices ("floors"). Not sure which gadgets
* contain multiple G4s in a cascaded configuration, if any.
*
*/
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/bch.h>
#include <linux/bitrev.h>
#include <linux/jiffies.h>
/*
* In "reliable mode" consecutive 2k pages are used in parallel (in some
* fashion) to store the same data. The data can be read back from the
* even-numbered pages in the normal manner; odd-numbered pages will appear to
* contain junk. Systems that boot from the docg4 typically write the secondary
* program loader (SPL) code in this mode. The SPL is loaded by the initial
* program loader (IPL, stored in the docg4's 2k NOR-like region that is mapped
* to the reset vector address). This module parameter enables you to use this
* driver to write the SPL. When in this mode, no more than 2k of data can be
* written at a time, because the addresses do not increment in the normal
* manner, and the starting offset must be within an even-numbered 2k region;
* i.e., invalid starting offsets are 0x800, 0xa00, 0xc00, 0xe00, 0x1800,
* 0x1a00, ... Reliable mode is a special case and should not be used unless
* you know what you're doing.
*/
static bool reliable_mode;
module_param(reliable_mode, bool, 0);
MODULE_PARM_DESC(reliable_mode, "pages are programmed in reliable mode");
/*
* You'll want to ignore badblocks if you're reading a partition that contains
* data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since
* it does not use mtd nand's method for marking bad blocks (using oob area).
* This will also skip the check of the "page written" flag.
*/
static bool ignore_badblocks;
module_param(ignore_badblocks, bool, 0);
MODULE_PARM_DESC(ignore_badblocks, "no badblock checking performed");
struct docg4_priv {
struct mtd_info *mtd;
struct device *dev;
void __iomem *virtadr;
int status;
struct {
unsigned int command;
int column;
int page;
} last_command;
uint8_t