Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1298773
  • 博文数量: 548
  • 博客积分: 7597
  • 博客等级: 少将
  • 技术积分: 4224
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-15 13:21
个人简介

嵌入式软件工程师&&太极拳

文章分类

全部博文(548)

文章存档

2014年(10)

2013年(76)

2012年(175)

2011年(287)

分类: 嵌入式

2012-05-09 11:11:27


点击(此处)折叠或打开

  1. 2410 nand flash的驱动文件
  2. #include <linux/slab.h>
  3. #include <linux/module.h>
  4. #include <linux/mtd/mtd.h>
  5. #include <linux/mtd/nand.h>
  6. #include <linux/mtd/compatmac.h>
  7. #include <linux/irq.h>
  8. #include <asm/io.h>
  9. #include <asm/hardware.h>
  10. #include <asm/sizes.h>
  11. #include <linux/compiler.h>
  12. #include <linux/delay.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/sched.h>
  15.                                                       
  16. static struct mtd_info * smc _mtd = NULL;
  17.                                                    
  18. #include <linux/mtd/partitions.h>
  19.                                                    
  20.   //对应于开发板的NAND Flash参数
  21. static struct mtd_partition smc_partitions[] = {
  22.     {
  23.         name:        "vivi",
  24.         size:        0x00030000,
  25.         offset:        0x0,
  26.         mask_flags:    MTD_WRITEABLE,
  27.     },{
  28.         name:        "kernel",
  29.         size:        0x000d0000,
  30.         offset:        0x00030000,
  31.         mask_flags:    MTD_WRITEABLE,    //force read-only
  32.     }, {
  33.         name:        "root",
  34.         size:        0x03200000,
  35.         offset:        0x00100000,
  36.         mask_flags:    MTD_WRITEABLE, // force read-only
  37.     },{
  38.         name: "user_file",
  39.                 size: 0x00A00000,
  40.                 offset: 0x03300000,
  41.     }
  42. };
  43.                                                                            
  44. static void smc_hwcontrol(int cmd) {
  45.     switch (cmd) {
  46.     case NAND_CTL_SETNCE:    NFCONF &= ~NFCONF_nFCE_HIGH; break;
  47.     case NAND_CTL_CLRNCE:    NFCONF |= NFCONF_nFCE_HIGH; break;
  48.     case NAND_CTL_SETCLE:    break;
  49.     case NAND_CTL_CLRCLE:    break;
  50.     case NAND_CTL_SETALE:    break;
  51.     case NAND_CTL_CLRALE:    break;
  52.     case NAND_CTL_DAT_IN:    break;
  53.     case NAND_CTL_DAT_OUT:    break;
  54.     }
  55. }
  56.  static void write_cmd(u_char val) {
  57.     NFCMD = (u_char) val;
  58. }

  59. static void write_addr(u_char val) {
  60.     NFADDR = (u_char) val;
  61. }

  62. static u_char read_data(void) {
  63.     return (u_char) NFDATA;
  64. }

  65. static void write_data(u_char val) {
  66.     NFDATA = (u_char) val;
  67. }

  68. static void wait_for_ready(void) {
  69.     while (!(NFSTAT & NFSTAT_RnB)) {
  70.       /**/
  71.       udelay(10);
  72.     }
  73. }

  74. inline int smc_insert(struct nand_chip *this) {
  75.     /* Scan to find existance of the device */
  76.     if (smc_scan (s3c2410_mtd)) {
  77.       return -ENXIO;
  78.     }
  79.     /* 为内部缓冲区分配内存 */
  80.     this->data_buf = kmalloc(sizeof(u_char) *
  81.              (s3c2410_mtd->oobblock + s3c2410_mtd->oobsize),
  82.              GFP_KERNEL);
  83.     if (!this->data_buf) {
  84.       printk ("Unable to allocate NAND data buffer for S3C2410.\n");
  85.       this->data_buf = NULL;
  86.       return -ENOMEM;
  87.     }
  88. #ifdef CONFIG_MTD_SMC_S3C2410_SMDK_PARTITION
  89.     add_mtd_partitions(s3c2410_mtd, &smc_partitions,
  90.          sizeof(smc_partitions)/sizeof(smc_partitions[0]));
  91. //#else
  92.     add_mtd_device(s3c2410_mtd);
  93. #endif

  94.     return 0;
  95. }

  96. inline void smc_remove(struct nand_chip *this) {
  97. #if defined(CONFIG_MTD_SMC_S3C2410_SMDK_PARTITION)
  98.     del_mtd_partitions(s3c2410_mtd);
  99. //#else
  100.     del_mtd_device(s3c2410_mtd);
  101. #endif

  102.     s3c2410_mtd->size = 0;
  103.     if (this->data_buf != NULL) {
  104.       /* 释放数据缓冲区*/
  105.       kfree (this->data_buf);
  106.       this->data_buf = NULL;
  107.     }
  108. }

  109. #ifdef CONFIG_PM
  110. static unsigned long nfcon;
  111. static int
  112. s3c2410_smc_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
  113. {
  114.     struct nand_chip *this = (struct nand_chip *)pm_dev->data;
  115.     switch (req) {
  116.         case PM_SUSPEND:
  117.             nfcon = NFCONF;
  118.             break;
  119.         case PM_RESUME:
  120.             NFCONF = nfcon;
  121.             /* 使能芯片-> 复位 -> 等待到可读 -> 屏蔽芯片 */
  122.             this->hwcontrol(NAND_CTL_SETNCE);
  123.             this->write_cmd(NAND_CMD_RESET);
  124.             this->wait_for_ready();
  125.             this->hwcontrol(NAND_CTL_CLRNCE);
  126.             break;

  127.     }
  128.     return 0;
  129. }
  130. #endif

  131. /*
  132.  * 主程序
  133.  */
  134. int __init smc_s3c2410_init (void)
  135. {
  136.     struct nand_chip *this;
  137.     u_int16_t nfconf;
  138.     /*为 MTD设备分配内存 */
  139.     s3c2410_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
  140.             GFP_KERNEL);
  141.     if (!s3c2410_mtd) {
  142.       printk ("Unable to allocate S3C2410 NAND MTD device structure.\n");
  143.       return -ENOMEM;
  144.     }

  145.     /* 取得指向数据的指针*/
  146.     this = (struct nand_chip *) (&s3c2410_mtd[1]);

  147.     /* 初始化结构 */
  148.     memset((char *) s3c2410_mtd, 0, sizeof(struct mtd_info));
  149.     memset((char *) this, 0, sizeof(struct nand_chip));

  150.       s3c2410_mtd->priv = this;

  151.     /* 设置闪存控制器*/
  152.     {
  153.       nfconf = NFCONF;
  154.       /* 使能闪存控制器*/
  155.       nfconf |= NFCONF_FCTRL_EN;

  156.       /* 设置闪存时序 */
  157.       nfconf &= ~NFCONF_TWRPH1; /* 0x0 */
  158.       nfconf |= NFCONF_TWRPH0_3; /* 0x3 */
  159.       nfconf &= ~NFCONF_TACLS; /* 0x0 */

  160.       NFCONF = nfconf;
  161.     }

  162.     /* 设置NAND的I/O地址 */
  163.     this->hwcontrol = smc_hwcontrol;
  164.     this->write_cmd = write_cmd;
  165.     this->write_addr = write_addr;
  166.     this->read_data = read_data;
  167.     this->write_data = write_data;
  168.     this->wait_for_ready = wait_for_ready;

  169.     /* 使能芯片-> 复位 -> 等待到可读 -> 屏蔽芯片 */
  170.     this->hwcontrol(NAND_CTL_SETNCE);
  171.     this->write_cmd(NAND_CMD_RESET);
  172.     this->wait_for_ready();
  173.     this->hwcontrol(NAND_CTL_CLRNCE);
  174.     smc_insert(this);
  175. #ifdef CONFIG_PM
  176.     smc_pm_dev = pm_register(PM_DEBUG_DEV, PM_SYS_MISC, s3c2410_smc_pm_callback);
  177.     if (smc_pm_dev)
  178.         smc_pm_dev->data = &s3c2410_mtd[1];
  179. #endif

  180.     return 0;
  181. }
  182. module_init(smc_s3c2410_init);

  183. #ifdef MODULE
  184. static void __exit smc_s3c2410_cleanup (void)
  185. {
  186.     struct nand_chip *this = (struct nand_chip *) &s3c2410_mtd[1];

  187.     smc_remove(this);

  188.     /* 释放MTD设备 */
  189.     kfree (s3c2410_mtd);
  190. }
  191. module_exit(smc_s3c2410_cleanup);
  192. #endif

  193. MODULE_LICENSE("GPL");
  194. MODULE_DESCRIPTION("SMC Card on S3C2410 board");


点击(此处)折叠或打开

  1. #ifdef CONFIG_MTD_PARTITIONS
  2. #include
  3. #endif

  4. #define WINDOW_ADDR 0x01000000 /* physical properties of flash */
  5. #define WINDOW_SIZE 0x800000
  6. #define BUSWIDTH 2
  7. #define FLASH_BLOCKSIZE_MAIN0x20000
  8. #define FLASH_NUMBLOCKS_MAIN128
  9. /* can be "cfi_probe", "jedec_probe", "map_rom", NULL }; */
  10. #define PROBETYPES { "cfi_probe", NULL }

  11. #define MSG_PREFIX "S3C2410-NOR:" /* prefix for our printk()'s */
  12. #define MTDID "s3c2410-nor" /* for mtdparts= partitioning */

  13. static struct mtd_info *mymtd;

  14. struct map_info s3c2410nor_map = {
  15. .name = "NOR flash on S3C2410",
  16. .size = WINDOW_SIZE,
  17. .bankwidth = BUSWIDTH,
  18. .phys = WINDOW_ADDR,
  19. };

  20. #ifdef CONFIG_MTD_PARTITIONS

  21. /*
  22. * MTD partitioning stuff
  23. */
  24. static struct mtd_partition static_partitions[] =
  25. {
  26. {
  27. .name = "BootLoader",
  28. .size = 0x040000,
  29. .offset = 0x0
  30. },
  31. {
  32. .name = "Kernel",
  33. .size = 0x0100000,
  34. .offset = 0x40000
  35. },
  36. {
  37. .name = "RamDisk",
  38. .size = 0x400000,
  39. .offset = 0x140000
  40. },
  41. {
  42. .name = "cramfs(2MB)",
  43. .size = 0x200000,
  44. .offset = 0x540000
  45. },
  46. {
  47. .name = "jffs2(0.75MB)",
  48. .size = 0xc0000,
  49. .offset = 0x740000
  50. },
  51. };

  52. //static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
  53. static const char *probes[] = { NULL };

  54. #endif

  55. static int mtd_parts_nb = 0;
  56. static struct mtd_partition *mtd_parts = 0;

  57. int __init init_s3c2410nor(void)
  58. {
  59. static const char *rom_probe_types[] = PROBETYPES;
  60. const char **type;
  61. const char *part_type = 0;

  62.       printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
  63.       WINDOW_SIZE, WINDOW_ADDR);
  64. s3c2410nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);

  65. if (!s3c2410nor_map.virt) {
  66. printk(MSG_PREFIX "failed to ioremap\n");
  67. return -EIO;
  68. }

  69. simple_map_init(&s3c2410nor_map);

  70. mymtd = 0;
  71. type = rom_probe_types;
  72. for(; !mymtd && *type; type++) {
  73. mymtd = do_map_probe(*type, &s3c2410nor_map);
  74. }
  75. if (mymtd) {
  76. mymtd->owner = THIS_MODULE;

  77. #ifdef CONFIG_MTD_PARTITIONS
  78. mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);
  79. if (mtd_parts_nb > 0)
  80.  part_type = "detected";

  81. if (mtd_parts_nb == 0)
  82. {
  83. mtd_parts = static_partitions;
  84. mtd_parts_nb = ARRAY_SIZE(static_partitions);
  85. part_type = "static";
  86. }
  87. #endif
  88. add_mtd_device(mymtd);
  89. if (mtd_parts_nb == 0)
  90.  printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
  91. else
  92. {
  93. printk(KERN_NOTICE MSG_PREFIX
  94.       "using %s partition definition\n", part_type);
  95. add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
  96. }
  97. return 0;
  98. }

  99. iounmap((void *)s3c2410nor_map.virt);
  100. return -ENXIO;
  101. }

  102. static void __exit cleanup_s3c2410nor(void)
  103. {
  104. if (mymtd) {
  105. del_mtd_device(mymtd);
  106. map_destroy(mymtd);
  107. }
  108. if (s3c2410nor_map.virt) {
  109. iounmap((void *)s3c2410nor_map.virt);
  110. s3c2410nor_map.virt = 0;
  111. }
  112. }

  113. module_init(init_s3c2410nor);
  114. module_exit(cleanup_s3c2410nor);
  115. MODULE_DESCRIPTION("Generic configurable MTD map driver");
阅读(467) | 评论(0) | 转发(1) |
0

上一篇:用c实现http协议

下一篇:norflash驱动写法

给主人留下些什么吧!~~