/*
参考下面两个驱动程序:
drivers\mtd\nand\s3c2410.c
drivers\mtd\namd\At91_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",
.offset = MTDPART_OFS_APPEND,
.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");
mini2440 NAND FLASH 驱动-----内核是2.6.32.2
最新推荐文章于 2024-08-30 14:11:28 发布