加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

mini2440 NAND FLASH 驱动-----内核是2.6.32.2

发布时间:2020-12-15 18:23:01 所属栏目:百科 来源:网络整理
导读:/*参考下面两个驱动程序:driversmtdnands3c2410.cdriversmtdnamdAt91_nand.c*/#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_d
/*
参考下面两个驱动程序:
driversmtdnands3c2410.c
driversmtdnamdAt91_nand.c

*/
#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/slab.h>
#include <linux/clk.h>
#include <linux/cpufreq.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 <plat/regs-nand.h>
#include <plat/nand.h>



struct s3c2440_nand_registers{
	unsigned long NFCONF;
	unsigned long NFCONT;
	unsigned long NFCMD;
	unsigned long NFADDR;
	unsigned long NFDATA;
	unsigned long NFMECC0;
	unsigned long NFMECC1;
	unsigned long NFSECC;
	unsigned long NFSTAT;
	unsigned long NFESTAT0;
	unsigned long NFESTAT1;
	unsigned long NFMECC0_1;
	unsigned long NFMECC1_1;
	unsigned long NFSECC_1;
	unsigned long NFSBLK_1;
	unsigned long NFEBLK_1;
};

static struct nand_chip *s3c_nand; //nand_chip是用来描述硬件相关的信息
static struct mtd_info *s3c_mtd;
static struct s3c2440_nand_registers *s3c2440_nand_registers;

static struct mtd_partition s3c2440_nand_part[] = {
	[0] = {
		.name	= "bootlpader",.size	= 0x00040000,.offset	= 0,},[1] = {
		.name	= "params",.offset = MTDPART_OFS_APPEND,.size	= 0X00020000,[2] = {
		.name	= "kernel",.size	= 0x00200000,[3] = {
		.name	= "root",.offset	= MTDPART_OFS_APPEND,.size	= MTDPART_SIZ_FULL,}
};



static void s3c2440_select_chip(struct mtd_info *mtd,int chip)
{
	if(chip == -1){
		/*取消选中	选中 NFCONT[1] 设置为1*/
		s3c2440_nand_registers->NFCONT |= (1<<1);
		
	}
	else{
		/*选中 NFCONT[1] 设置为0*/
		s3c2440_nand_registers->NFCONT &= ~(1<<1);
	}

}
static void	s3c2440_cmd_ctrl(struct mtd_info *mtd,int data,unsigned int ctrl)
{
	if(ctrl & NAND_CLE){
		/*发命令:NFCMMD = data*/
		s3c2440_nand_registers->NFCMD = data;
	}
	else {
		/*地址:NFADDR = data*/
		s3c2440_nand_registers->NFADDR= data;
	}
}
static int	s3c_nand_dev_ready(struct mtd_info *mtd)
{
	return (s3c2440_nand_registers->NFSTAT & (1<<0));//"NFSTAT[0]的值"
}
static int __init s3c_nand_init(void)
{
	
	struct clk *clk;//设置使能时钟,总开关
	/*1.分配一个nand_chip结构体*/
	s3c_nand  = kzalloc(sizeof(struct nand_chip),GFP_KERNEL);
	

	s3c2440_nand_registers = ioremap(0x4E000000,sizeof(struct s3c2440_nand_registers));
	
	/*2.设置*/

	
	/*设置nand_chip是给nand_scan函数使用的,如果不知道怎么设置,先看看nand_scan是怎么使用的*/
	/*nand_chip应该提供:选中,发命令,发地址,发数据,判断状态的功能*/
	s3c_nand->select_chip = s3c2440_select_chip;//选中或者不选中 NAND FLASH 
	
	s3c_nand->cmd_ctrl    = s3c2440_cmd_ctrl;
	
	s3c_nand->IO_ADDR_R   = &(s3c2440_nand_registers->NFDATA);//"NFDATA的虚拟地址";
	
	s3c_nand->IO_ADDR_W   = &(s3c2440_nand_registers->NFDATA);//"NFDATA的虚拟地址";
	s3c_nand->dev_ready   = s3c_nand_dev_ready;
	s3c_nand->ecc.mode    = NAND_ECC_SOFT;//设置ECC

	/*3.硬件相关的操作:根据NAND FLASH的时间参数设置寄存器*/

	/*在设置硬件之前,应该先设置使能时钟*/
	clk = clk_get(NULL,"nand");
	clk_enable(clk);           /*设置的是CLKCON[4]=1*/
	
	/*HCLK :101.250MHz*/
	/*
	寄存器:NFCONF
	TACLS [13:12]: = 0  根据时序图和手册可以计算出来
	TWRPH0[10: 8]: = 1
	TWRPH1[ 6: 4]: = 0
	*/
	s3c2440_nand_registers->NFCONF |= (0<<12 | ( 1<<8 ) | (0<<4));

	/*
	寄存器:NFCONT寄存器
	NFCONT[1]: =0  取消片选   =1 选中芯片
	NFCONT[0]: =0  禁止NAND FLASH 控制器  =1 使能NAND FALSH 控制器
	*/
	s3c2440_nand_registers->NFCONT |= ((1<<1)|(1<<0));

	
	/*4.使用:nand_scan扫面nand flash*/
	s3c_mtd = kzalloc(sizeof(struct mtd_info),GFP_KERNEL);
	//s3c_mtd和s3c_nand怎么挂钩起来呢?
	s3c_mtd->owner = THIS_MODULE;
	s3c_mtd->priv = s3c_nand;//这里挂钩起来
	
	nand_scan(s3c_mtd,1);//怎么把nand_scan用起来,nand_scan第二参数表示最大芯片个数
	//nand_scan的作用识别NAND FLASH,构造mtd_info结构体

	
	/*5.add_mtd_partitions:增加MTD分区*/

   add_mtd_partitions(s3c_mtd,s3c2440_nand_part,4);
	
	//add_mtd_device(s3c_mtd);不用构造分区
	/*
	内核的分区
	0x000000000000-0x000000040000 : "supervivi"
	uncorrectable error : 
	0x000000040000-0x000000060000 : "param"
	ftl_cs: FTL header not found.
	0x000000060000-0x000000560000 : "Kernel"
	ftl_cs: FTL header not found.
	0x000000560000-0x000040560000 : "root"
	*/
	return 0;
}
static void __exit s3c_nand_exit(void)
{
	del_mtd_partitions(s3c_mtd);
	kfree(s3c_mtd);
	iounmap(s3c2440_nand_registers);
	kfree(s3c_nand);
}
module_init(s3c_nand_init);
module_exit(s3c_nand_exit);
MODULE_LICENSE("GPL");

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读