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