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"); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |