mtd/drivers/mtd/nand diskonchip.c,1.3,1.4
David Woodhouse
dwmw2 at infradead.org
Fri Jul 11 11:06:44 EDT 2003
Update of /home/cvs/mtd/drivers/mtd/nand
In directory phoenix.infradead.org:/tmp/cvs-serv10785
Modified Files:
diskonchip.c
Log Message:
Scan all chips
Index: diskonchip.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nand/diskonchip.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- diskonchip.c 9 Jul 2003 11:24:17 -0000 1.3
+++ diskonchip.c 11 Jul 2003 15:06:42 -0000 1.4
@@ -25,7 +25,7 @@
unsigned long physadr;
u_char ChipID;
u_char CDSNControl;
- int floorshift; /* The number of chips detected on each floor */
+ int chips_per_floor; /* The number of chips detected on each floor */
int curfloor;
int curchip;
};
@@ -34,6 +34,7 @@
#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd);
+static void doc200x_select_chip(struct mtd_info *mtd, int chip);
static int debug=0;
MODULE_PARM(debug, "i");
@@ -158,6 +159,45 @@
return 0;
}
+static uint16_t doc2000_ident_chip(struct mtd_info *mtd, int nr)
+{
+ uint16_t ret;
+
+ doc200x_select_chip(mtd, nr);
+ doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
+ doc2000_write_byte(mtd, NAND_CMD_READID);
+ doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
+ doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
+ doc2000_write_byte(mtd, 0);
+ doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
+
+ ret = doc2000_read_byte(mtd) << 8;
+ ret |= doc2000_read_byte(mtd);
+
+ return ret;
+}
+
+static void doc2000_count_chips(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ uint16_t mfrid;
+ int i;
+
+ /* Max 4 chips per floor on DiskOnChip 2000 */
+ doc->chips_per_floor = 4;
+
+ /* Find out what the first chip is */
+ mfrid = doc2000_ident_chip(mtd, 0);
+
+ /* Find how many chips in each floor. */
+ for (i = 1; i < 4; i++) {
+ if (doc2000_ident_chip(mtd, i) != mfrid)
+ break;
+ }
+ doc->chips_per_floor = i;
+}
+
static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
{
struct doc_priv *doc = (void *)this->priv;
@@ -170,7 +210,6 @@
status = (int)this->read_byte(mtd);
return status;
-
}
static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
@@ -254,19 +293,17 @@
unsigned long docptr = doc->virtadr;
int floor = 0;
-#if 0
- floor = chip >> doc->floorshift;
- chip -= (floor << doc->floorshift);
-#endif
-
/* 11.4.4 -- deassert CE before changing chip */
doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
- if(debug)printk("select chip %d\n", chip);
+ if(debug)printk("select chip (%d)\n", chip);
if (chip == -1)
return;
+ floor = chip / doc->chips_per_floor;
+ chip -= (floor * doc->chips_per_floor);
+
WriteDOC(floor, docptr, FloorSelect);
WriteDOC(chip, docptr, CDSNDeviceSelect);
@@ -360,6 +397,7 @@
int __init init_nanddoc(void)
{
mydoc.virtadr = (unsigned long)ioremap(mydoc.physadr, DOC_IOREMAP_LEN);
+ int nrchips = 1;
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
mydoc.virtadr, DOCControl);
@@ -380,6 +418,10 @@
mynand.write_buf = doc2001_writebuf;
mynand.read_buf = doc2001_readbuf;
mynand.verify_buf = doc2001_verifybuf;
+
+ /* Millennium only ever has one chip, apparently */
+ mydoc.chips_per_floor = 1;
+ nrchips = 1;
break;
case DOC_ChipID_Doc2k:
@@ -388,12 +430,16 @@
mynand.write_buf = doc2000_writebuf;
mynand.read_buf = doc2000_readbuf;
mynand.verify_buf = doc2000_verifybuf;
+
+ doc2000_count_chips(&mymtd);
+ nrchips = 4 * mydoc.chips_per_floor;
+
break;
default:
return -EIO;
}
- if (nand_scan(&mymtd)) {
+ if (nand_scan(&mymtd, nrchips)) {
iounmap((void *)mydoc.virtadr);
return -EIO;
}
More information about the linux-mtd-cvs
mailing list