2014-04-17 nand flash驱动程序__

来源:互联网 发布:fifa online3改键软件 编辑:程序博客网 时间:2024/05/29 07:38

实验描述:

nand flash驱动程序


内核版本:

Linux 2.6.38


开发板: 

Mini 6410


如何确定参数时间的大小:

s3c6410手册:



nand flash手册:



程序实现:

#include <linux/init.h>  #include <linux/module.h>  #include <linux/device.h>#include <linux/cdev.h> #include <linux/fs.h> #include <linux/slab.h>#include <linux/delay.h>#include <linux/clk.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <linux/time.h>#include <linux/interrupt.h>#include <linux/io.h>#include <linux/err.h>#include <linux/mtd/mtd.h>#include <linux/mtd/nand.h>#include <linux/mtd/nand_ecc.h>#include <linux/mtd/partitions.h>#define PRINTK printk//#define PRINTK(...) struct s3c6410_nand_regs {unsigned long nfconf  ;unsigned long nfcont  ;unsigned long nfcmd   ;unsigned long nfaddr  ;unsigned long nfdata  ;unsigned long nfeccd0 ;unsigned long nfeccd1 ;unsigned long nfeccd  ;unsigned long nfsblk  ;unsigned long nfeblk  ;unsigned long nfstat  ;unsigned long nfeccrr0 ;unsigned long nfeccrr1 ;unsigned long nfmecc0 ;unsigned long nfmecc1 ;unsigned long nfsecc ;unsigned long nfmlcbitpt;unsigned long nf8eccerr0;unsigned long nf8eccerr1;unsigned long nf8eccerr2;unsigned long nfm8ecc0 ;unsigned long nfm8ecc1 ;unsigned long nfm8ecc2 ;unsigned long nfm8ecc3 ;unsigned long nfmlc8bitpt0;unsigned long nfmlc8bitpt1;};static struct nand_chip *s3c6410_nand_chips;static struct s3c6410_nand_regs *s3c6410_nand_regs;static struct clk *nand_clk;static struct mtd_info *s3c6410_mtd_info;static struct mtd_partition s3c6410_nand_parts[] = {[0] = {.name   = "bootloader",.size   = 0x000000080000,.offset= 0,},[1] = {.name   = "kernel",.offset = MTDPART_OFS_APPEND,.size   = 0x000000500000,},[2] = {.name   = "file system",.offset = MTDPART_OFS_APPEND,.size   = MTDPART_SIZ_FULL,}};void nand_select_chip(struct mtd_info *mtd, int chip){if (chip == -1){s3c6410_nand_regs->nfcont |= (1<<1);//cancle selectPRINTK(KERN_ALERT"cancle select!\n");}else{s3c6410_nand_regs->nfcont &= ~(1<<1); //enable selectPRINTK(KERN_ALERT"enable select!\n");}}void nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl){if (ctrl & NAND_CLE){s3c6410_nand_regs->nfcmd = dat;//send  commandPRINTK(KERN_ALERT"send  command\n");}else{s3c6410_nand_regs->nfaddr = dat; //send  addressPRINTK(KERN_ALERT"send  address\n");}}int nand_dev_ready(struct mtd_info *mtd){PRINTK(KERN_ALERT"read:%d\n", s3c6410_nand_regs->nfstat & (1<<0));return (s3c6410_nand_regs->nfstat & (1<<0));}static int nand_driver_init(void)  {   int err;s3c6410_nand_chips = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);if(!s3c6410_nand_chips){err = -ENOMEM;PRINTK(KERN_ALERT"s3c6410_nand_chips kzalloc busy!\n");goto out_err;}s3c6410_nand_regs = ioremap(0x70200000, sizeof(struct s3c6410_nand_regs));if(!s3c6410_nand_regs){err = -EIO;PRINTK(KERN_ALERT"ioreamp to s3c6410_nand_regs fail!\n");goto out_err;}s3c6410_nand_chips->select_chip = nand_select_chip;s3c6410_nand_chips->cmd_ctrl = nand_cmd_ctrl;s3c6410_nand_chips->IO_ADDR_R = &s3c6410_nand_regs->nfdata;s3c6410_nand_chips->IO_ADDR_W = &s3c6410_nand_regs->nfdata;s3c6410_nand_chips->dev_ready = nand_dev_ready;s3c6410_nand_chips->ecc.mode = NAND_ECC_SOFT;nand_clk = clk_get(NULL, "nand"); //we can also use 6410 guide to set clkclk_enable(nand_clk);#define TACLS    0#define TWRPH0   1#define TWRPH1   0//3.3V, As tclh>=5ns,twp>=12ns,tcls>=12ns, HCLK=10ns, so TACLS=0, TWRPH0=3(1/400)s3c6410_nand_regs->nfconf = (TACLS << 12) | (TWRPH0 << 8) | (TWRPH1 << 4);s3c6410_nand_regs->nfcont = (1 << 0) | (1 << 1);//select and enables3c6410_mtd_info = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);if(!s3c6410_mtd_info){err = -ENOMEM;PRINTK(KERN_ALERT"s3c6410_mtd_info kzalloc busy!\n");goto out_err;}s3c6410_mtd_info->owner = THIS_MODULE;s3c6410_mtd_info->priv =s3c6410_nand_chips;if(nand_scan(s3c6410_mtd_info, 1)){//scan nand flash to produce mtd_infoerr = -ENXIO;goto out_err;}  add_mtd_partitions(s3c6410_mtd_info, s3c6410_nand_parts, 3);PRINTK(KERN_ALERT"init!\n");return 0;out_err:if(s3c6410_mtd_info)kfree(s3c6410_mtd_info);if(s3c6410_nand_regs)iounmap(s3c6410_nand_regs);if(s3c6410_nand_chips)kfree(s3c6410_nand_chips);return err;}  static int nand_driver_exit(void)  {   del_mtd_partitions(s3c6410_mtd_info);if(s3c6410_mtd_info)kfree(s3c6410_mtd_info);if(s3c6410_nand_regs)iounmap(s3c6410_nand_regs);if(s3c6410_nand_chips)kfree(s3c6410_nand_chips);PRINTK(KERN_ALERT"exit!\n");return 0;  }   module_init(nand_driver_init);  module_exit(nand_driver_exit);MODULE_LICENSE("GPL");  MODULE_DESCRIPTION("S3C6410 nand flash driver");MODULE_AUTHOR("Books, <uppour@sina.cn>");


0 0
原创粉丝点击