⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtdnand.tmpl

📁 linux 内核源代码
💻 TMPL
📖 第 1 页 / 共 3 页
字号:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []><book id="MTD-NAND-Guide"> <bookinfo>  <title>MTD NAND Driver Programming Interface</title>    <authorgroup>   <author>    <firstname>Thomas</firstname>    <surname>Gleixner</surname>    <affiliation>     <address>      <email>tglx@linutronix.de</email>     </address>    </affiliation>   </author>  </authorgroup>  <copyright>   <year>2004</year>   <holder>Thomas Gleixner</holder>  </copyright>  <legalnotice>   <para>     This documentation is free software; you can redistribute     it and/or modify it under the terms of the GNU General Public     License version 2 as published by the Free Software Foundation.   </para>         <para>     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.   </para>         <para>     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   </para>         <para>     For more details see the file COPYING in the source     distribution of Linux.   </para>  </legalnotice> </bookinfo><toc></toc>  <chapter id="intro">      <title>Introduction</title>  <para>  	The generic NAND driver supports almost all NAND and AG-AND based	chips and connects them to the Memory Technology Devices (MTD)	subsystem of the Linux Kernel.  </para>  <para>  	This documentation is provided for developers who want to implement	board drivers or filesystem drivers suitable for NAND devices.  </para>  </chapter>    <chapter id="bugs">     <title>Known Bugs And Assumptions</title>  <para>	None.	  </para>  </chapter>  <chapter id="dochints">     <title>Documentation hints</title>     <para>     The function and structure docs are autogenerated. Each function and      struct member has a short description which is marked with an [XXX] identifier.     The following chapters explain the meaning of those identifiers.     </para>     <sect1>   	<title>Function identifiers [XXX]</title>     	<para>	The functions are marked with [XXX] identifiers in the short	comment. The identifiers explain the usage and scope of the	functions. Following identifiers are used:     	</para>	<itemizedlist>		<listitem><para>	  	[MTD Interface]</para><para>		These functions provide the interface to the MTD kernel API. 		They are not replacable and provide functionality		which is complete hardware independent.		</para></listitem>		<listitem><para>	  	[NAND Interface]</para><para>		These functions are exported and provide the interface to the NAND kernel API. 		</para></listitem>		<listitem><para>	  	[GENERIC]</para><para>		Generic functions are not replacable and provide functionality		which is complete hardware independent.		</para></listitem>		<listitem><para>	  	[DEFAULT]</para><para>		Default functions provide hardware related functionality which is suitable		for most of the implementations. These functions can be replaced by the		board driver if neccecary. Those functions are called via pointers in the		NAND chip description structure. The board driver can set the functions which		should be replaced by board dependent functions before calling nand_scan().		If the function pointer is NULL on entry to nand_scan() then the pointer		is set to the default function which is suitable for the detected chip type.		</para></listitem>	</itemizedlist>     </sect1>     <sect1>   	<title>Struct member identifiers [XXX]</title>     	<para>	The struct members are marked with [XXX] identifiers in the 	comment. The identifiers explain the usage and scope of the	members. Following identifiers are used:     	</para>	<itemizedlist>		<listitem><para>	  	[INTERN]</para><para>		These members are for NAND driver internal use only and must not be		modified. Most of these values are calculated from the chip geometry		information which is evaluated during nand_scan().		</para></listitem>		<listitem><para>	  	[REPLACEABLE]</para><para>		Replaceable members hold hardware related functions which can be 		provided by the board driver. The board driver can set the functions which		should be replaced by board dependent functions before calling nand_scan().		If the function pointer is NULL on entry to nand_scan() then the pointer		is set to the default function which is suitable for the detected chip type.		</para></listitem>		<listitem><para>	  	[BOARDSPECIFIC]</para><para>		Board specific members hold hardware related information which must		be provided by the board driver. The board driver must set the function		pointers and datafields before calling nand_scan().		</para></listitem>		<listitem><para>	  	[OPTIONAL]</para><para>		Optional members can hold information relevant for the board driver. The		generic NAND driver code does not use this information.		</para></listitem>	</itemizedlist>     </sect1>  </chapter>     <chapter id="basicboarddriver">     	<title>Basic board driver</title>	<para>		For most boards it will be sufficient to provide just the		basic functions and fill out some really board dependent		members in the nand chip description structure.	</para>	<sect1>		<title>Basic defines</title>		<para>			At least you have to provide a mtd structure and			a storage for the ioremap'ed chip address.			You can allocate the mtd structure using kmalloc			or you can allocate it statically.			In case of static allocation you have to allocate			a nand_chip structure too.		</para>		<para>			Kmalloc based example		</para>		<programlisting>static struct mtd_info *board_mtd;static unsigned long baseaddr;		</programlisting>		<para>			Static example		</para>		<programlisting>static struct mtd_info board_mtd;static struct nand_chip board_chip;static unsigned long baseaddr;		</programlisting>	</sect1>	<sect1>		<title>Partition defines</title>		<para>			If you want to divide your device into partitions, then			enable the configuration switch CONFIG_MTD_PARTITIONS and define			a partitioning scheme suitable to your board.		</para>		<programlisting>#define NUM_PARTITIONS 2static struct mtd_partition partition_info[] = {	{ .name = "Flash partition 1",	  .offset =  0,	  .size =    8 * 1024 * 1024 },	{ .name = "Flash partition 2",	  .offset =  MTDPART_OFS_NEXT,	  .size =    MTDPART_SIZ_FULL },};		</programlisting>	</sect1>	<sect1>		<title>Hardware control function</title>		<para>			The hardware control function provides access to the 			control pins of the NAND chip(s). 			The access can be done by GPIO pins or by address lines.			If you use address lines, make sure that the timing			requirements are met.		</para>		<para>			<emphasis>GPIO based example</emphasis>		</para>		<programlisting>static void board_hwcontrol(struct mtd_info *mtd, int cmd){	switch(cmd){		case NAND_CTL_SETCLE: /* Set CLE pin high */ break;		case NAND_CTL_CLRCLE: /* Set CLE pin low */ break;		case NAND_CTL_SETALE: /* Set ALE pin high */ break;		case NAND_CTL_CLRALE: /* Set ALE pin low */ break;		case NAND_CTL_SETNCE: /* Set nCE pin low */ break;		case NAND_CTL_CLRNCE: /* Set nCE pin high */ break;	}}		</programlisting>		<para>			<emphasis>Address lines based example.</emphasis> It's assumed that the			nCE pin is driven by a chip select decoder.		</para>		<programlisting>static void board_hwcontrol(struct mtd_info *mtd, int cmd){	struct nand_chip *this = (struct nand_chip *) mtd->priv;	switch(cmd){		case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT;  break;		case NAND_CTL_CLRCLE: this->IO_ADDR_W &amp;= ~CLE_ADRR_BIT; break;		case NAND_CTL_SETALE: this->IO_ADDR_W |= ALE_ADRR_BIT;  break;		case NAND_CTL_CLRALE: this->IO_ADDR_W &amp;= ~ALE_ADRR_BIT; break;	}}		</programlisting>	</sect1>	<sect1>		<title>Device ready function</title>		<para>			If the hardware interface has the ready busy pin of the NAND chip connected to a			GPIO or other accesible I/O pin, this function is used to read back the state of the			pin. The function has no arguments and should return 0, if the device is busy (R/B pin 			is low) and 1, if the device is ready (R/B pin is high).			If the hardware interface does not give access to the ready busy pin, then			the function must not be defined and the function pointer this->dev_ready is set to NULL.				</para>	</sect1>	<sect1>		<title>Init function</title>		<para>			The init function allocates memory and sets up all the board			specific parameters and function pointers. When everything			is set up nand_scan() is called. This function tries to			detect and identify then chip. If a chip is found all the			internal data fields are initialized accordingly.			The structure(s) have to be zeroed out first and then filled with the neccecary 			information about the device.		</para>		<programlisting>int __init board_init (void){	struct nand_chip *this;	int err = 0;	/* Allocate memory for MTD device structure and private data */	board_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);	if (!board_mtd) {		printk ("Unable to allocate NAND MTD device structure.\n");		err = -ENOMEM;		goto out;	}	/* map physical address */	baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);	if(!baseaddr){		printk("Ioremap to access NAND chip failed\n");		err = -EIO;		goto out_mtd;	}	/* Get pointer to private data */	this = (struct nand_chip *) ();	/* Link the private data with the MTD structure */	board_mtd->priv = this;	/* Set address of NAND IO lines */	this->IO_ADDR_R = baseaddr;	this->IO_ADDR_W = baseaddr;	/* Reference hardware control function */	this->hwcontrol = board_hwcontrol;	/* Set command delay time, see datasheet for correct value */	this->chip_delay = CHIP_DEPENDEND_COMMAND_DELAY;	/* Assign the device ready function, if available */	this->dev_ready = board_dev_ready;	this->eccmode = NAND_ECC_SOFT;	/* Scan to find existence of the device */	if (nand_scan (board_mtd, 1)) {		err = -ENXIO;		goto out_ior;	}		add_mtd_partitions(board_mtd, partition_info, NUM_PARTITIONS);	goto out;out_ior:	iounmap((void *)baseaddr);out_mtd:	kfree (board_mtd);out:	return err;}module_init(board_init);		</programlisting>	</sect1>	<sect1>		<title>Exit function</title>		<para>			The exit function is only neccecary if the driver is			compiled as a module. It releases all resources which			are held by the chip driver and unregisters the partitions			in the MTD layer.		</para>		<programlisting>#ifdef MODULEstatic void __exit board_cleanup (void){	/* Release resources, unregister device */	nand_release (board_mtd);	/* unmap physical address */	iounmap((void *)baseaddr);		/* Free the MTD device structure */	kfree (board_mtd);}module_exit(board_cleanup);#endif		</programlisting>	</sect1>  </chapter>  <chapter id="boarddriversadvanced">     	<title>Advanced board driver functions</title>	<para>		This chapter describes the advanced functionality of the NAND		driver. For a list of functions which can be overridden by the board		driver see the documentation of the nand_chip structure.	</para>	<sect1>		<title>Multiple chip control</title>		<para>			The nand driver can control chip arrays. Therefor the			board driver must provide an own select_chip function. This			function must (de)select the requested chip.			The function pointer in the nand_chip structure must			be set before calling nand_scan(). The maxchip parameter			of nand_scan() defines the maximum number of chips to			scan for. Make sure that the select_chip function can			handle the requested number of chips.		</para>		<para>			The nand driver concatenates the chips to one virtual			chip and provides this virtual chip to the MTD layer.		</para>		<para>			<emphasis>Note: The driver can only handle linear chip arrays			of equally sized chips. There is no support for			parallel arrays which extend the buswidth.</emphasis>		</para>		<para>			<emphasis>GPIO based example</emphasis>		</para>		<programlisting>static void board_select_chip (struct mtd_info *mtd, int chip){	/* Deselect all chips, set all nCE pins high */	GPIO(BOARD_NAND_NCE) |= 0xff;		if (chip >= 0)		GPIO(BOARD_NAND_NCE) &amp;= ~ (1 &lt;&lt; chip);}		</programlisting>		<para>			<emphasis>Address lines based example.</emphasis>			Its assumed that the nCE pins are connected to an			address decoder.		</para>		<programlisting>static void board_select_chip (struct mtd_info *mtd, int chip){	struct nand_chip *this = (struct nand_chip *) mtd->priv;		/* Deselect all chips */	this->IO_ADDR_R &amp;= ~BOARD_NAND_ADDR_MASK;	this->IO_ADDR_W &amp;= ~BOARD_NAND_ADDR_MASK;	switch (chip) {	case 0:		this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0;		this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0;		break;	....		case n:		this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn;		this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn;		break;	}	}		</programlisting>	</sect1>	<sect1>		<title>Hardware ECC support</title>		<sect2>			<title>Functions and constants</title>			<para>				The nand driver supports three different types of				hardware ECC.				<itemizedlist>				<listitem><para>NAND_ECC_HW3_256</para><para>				Hardware ECC generator providing 3 bytes ECC per				256 byte.				</para>	</listitem>				<listitem><para>NAND_ECC_HW3_512</para><para>				Hardware ECC generator providing 3 bytes ECC per				512 byte.				</para>	</listitem>				<listitem><para>NAND_ECC_HW6_512</para><para>				Hardware ECC generator providing 6 bytes ECC per				512 byte.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -