mini2440 简单nandflash驱动代码记录(2.6.32.2内核)
发布时间:2020-12-15 07:01:12 所属栏目:百科 来源:网络整理
导读:#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
#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> static struct nand_chip *mini2440_nand; static struct mtd_info *mini2440_mtd_info; static struct nand_regs_t{ unsigned long NFCONF; unsigned long NFCONT; unsigned long NFCMD; unsigned long NFADDR; unsigned long NFDATA; unsigned long NFMECCD0; unsigned long NFMECCD1; unsigned long NFSECCD; unsigned long NFSTAT; unsigned long NFESTAT0; unsigned long NFESTAT1; unsigned long NFMECC0; unsigned long NFMECC1; unsigned long NFSECC; unsigned long NFSBLK; unsigned long NFEBLK; }; static volatile struct nand_regs_t *nand_regs; static void grh_select_chip(struct mtd_info *mtd,int chipnr){ if(-1 == chipnr){ //取消选中nfcont[1] = 1 nand_regs->NFCONT |= (1<<1); } else{ //选中芯片 nfcont[1] = 0 nand_regs->NFCONT &= ~(1<<1); } } static void grh_cmd_ctrl(struct mtd_info *mtd,int dat,unsigned int ctrl){ if(ctrl & NAND_CLE){ //发送命令 nfcmmd = dat nand_regs->NFCMD = dat; } else{ //发送地址 nfaddr = dat nand_regs->NFADDR = dat; } } static int grh_dev_ready(struct mtd_info *mdt){ //return nfstat[0] return nand_regs->NFSTAT &(1<<0); } //falsh分区表 static struct mtd_partition grh_nand_parts[] = { [0] = { .name = "grh_supervivi",.size = 0x00040000,.offset = 0,},[1] = { .name = "grh_param",.offset = 0x00040000,.size = 0x00020000,[2] = { .name = "grh_Kernel",.offset = 0x00060000,.size = 0x00500000,[3] = { .name = "grh_root",.offset = 0x00560000,.size = 1024 * 1024 * 1024,// },[4] = { .name = "grh_nand",.offset = 0x00000000,// } }; static int nand_init(void){ struct clk *clk; /*分配nand_chip结构体 该结构体里面需要提供对nandflash的硬件操作(发命令,发数据,读数据,复位,选通等)的 具体实现,mtd_info实现了怎么用命令来操作flash,而nand_chip就得在更低一层对命令进行实现 */ mini2440_nand = kzalloc(sizeof(struct nand_chip),GFP_KERNEL); nand_regs = ioremap(0x4e000000,sizeof(struct nand_regs_t)); //设置参数 mini2440_nand->select_chip = grh_select_chip; //设置选中芯片的函数 mini2440_nand->cmd_ctrl = grh_cmd_ctrl; //设置发送命令和地址的函数 mini2440_nand->IO_ADDR_R = &(nand_regs->NFDATA); //nfdata虚拟地址 mini2440_nand->IO_ADDR_W = &(nand_regs->NFDATA); //nfdata虚拟地址 mini2440_nand->dev_ready = grh_dev_ready; //判断芯片是否就绪的函数 mini2440_nand->ecc.mode = NAND_ECC_SOFT; //软件生成ECC校验码,存入OOB区 //使能nandflash控制器的时钟,才能操作相关的寄存器 clk = clk_get(NULL,"nand"); clk_enable(clk); //设置硬件相关的时间参数 nand_regs->NFCONF = 0<<12; //TACLS=0 nand_regs->NFCONF |= (1<<8); //TWRPH0=1 nand_regs->NFCONF |= (0<<4); //TWRPH1=0 nand_regs->NFCONT |= (1<<1); //先不选中芯片 nand_regs->NFCONT |= (1<<0); //使能nandflash控制器 //使用nand_chip mini2440_mtd_info = kzalloc(sizeof(struct mtd_info),GFP_KERNEL); mini2440_mtd_info->owner = THIS_MODULE; mini2440_mtd_info->priv = mini2440_nand; //扫描识别芯片构造mtd_info结构体,mtd_info确定了对flash进行读写需要怎么发送命令 nand_scan(mini2440_mtd_info,1); //add_mtd_partition划分flash的分区 add_mtd_partitions(mini2440_mtd_info,grh_nand_parts,5); return 0; } static void nand_exit(void){ iounmap(nand_regs); kfree(mini2440_nand); kfree(mini2440_mtd_info); return ; } module_init(nand_init); module_exit(nand_exit); MODULE_AUTHOR("GRH"); MODULE_VERSION("1.0"); MODULE_DESCRIPTION("NAND FLASH DRIVER"); MODULE_LICENSE("GPL"); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |