📄 s3c24a0_smc.c
字号:
}void s3csmc_readecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code){}void s3csmc_device_setup(void){ elfin_nand_init_controller();}static u_char s3csmc_nand_read_byte(struct mtd_info *mtd){ return elfin_nand_get_data();}static void s3csmc_nand_write_byte(struct mtd_info *mtd, u_char byte){ elfin_nand_put_data(byte);}static void s3csmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len){ int i; for (i=0; i<len; i++) elfin_nand_put_data(buf[i]);}static void s3csmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len){ int i; for (i=0; i<len; i++) buf[i] = elfin_nand_get_data();}static int s3csmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len){ int i; for (i=0; i<len; i++) if (buf[i] != elfin_nand_get_data()) return -EFAULT; return 0;}/* * Send command to NAND device */static void s3csmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr){ register struct nand_chip *this = mtd->priv; int i; /* * Write out the command to the device. */ if (command == NAND_CMD_SEQIN) { unsigned setptr; if (mtd->oobblock == 256 && column >= 256) { column -= 256; setptr = NAND_CMD_READOOB; } else if (mtd->oobblock == 512 && column >= 256) { if (column < 512) { column -= 256; setptr = NAND_CMD_READ1; } else { column -= 512; setptr = NAND_CMD_READOOB; } } else { setptr = NAND_CMD_READ0; } elfin_nand_put_cmd (setptr); } elfin_nand_put_cmd (command); /* Start address cycle */ if (column != -1 || page_addr != -1) { /* Serially input address */ if (column != -1) elfin_nand_put_addr (column); if (page_addr != -1) { elfin_nand_put_addr (page_addr & 0xff); elfin_nand_put_addr ((page_addr >> 8) & 0xff); /* One more address cycle for higher density devices */ if (mtd->size & 0x0c000000) elfin_nand_put_addr ((page_addr >> 16) & 0x0f); } } /* * program and erase have their own busy handlers * status and sequential in needs no delay */ switch (command) { #if 0 case NAND_CMD_SEQIN: case NAND_CMD_PAGEPROG: case NAND_CMD_ERASE1: case NAND_CMD_ERASE2: return; return;#endif case NAND_CMD_STATUS: case NAND_CMD_READID: for(i=0; i<30; i++); /* Wait for tWHR(min 60ns) */ return; case NAND_CMD_RESET: case NAND_CMD_READ0: case NAND_CMD_READ1: case NAND_CMD_READOOB: for(i=0; i<40; i++); /* Wait for tWB(max 100ns) */ while (!this->dev_ready(mtd)); } return;} /* * Main initialization routine */extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);int __init s3csmc_init (void){ struct nand_chip *this; int err = 0; /* Allocate memory for MTD device structure and private data */ s3csmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL); if (!s3csmc_mtd) { printk ("Unable to allocate S3C24A0 NAND MTD device structure.\n"); err = -ENOMEM; goto out; } s3csmc_device_setup(); /* io is indirect via a register so don't need to ioremap address */ /* Get pointer to private data */ this = (struct nand_chip *) (&s3csmc_mtd[1]); /* Initialize structures */ memset((char *) s3csmc_mtd, 0, sizeof(struct mtd_info)); memset((char *) this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ s3csmc_mtd->priv = this; /* Set address of NAND IO lines */ this->hwcontrol = s3csmc_hwcontrol; this->enable_hwecc = s3csmc_enable_hwecc; this->calculate_ecc = s3csmc_readecc; this->correct_data = nand_correct_data; /*this->eccmode = NAND_ECC_SOFT;*/ this->eccmode = NAND_ECC_NONE; this->dev_ready = s3csmc_device_ready; /* 20 us command delay time */ this->chip_delay = 1; this->read_byte = s3csmc_nand_read_byte; this->write_byte = s3csmc_nand_write_byte; this->cmdfunc = s3csmc_nand_command; this->write_buf = s3csmc_nand_write_buf; this->read_buf = s3csmc_nand_read_buf; this->verify_buf = s3csmc_nand_verify_buf; /* Scan to find existance of the device */ if (nand_scan (s3csmc_mtd, 1)) { err = -ENXIO; goto out_ior; } /* Allocate memory for internal data buffer */ this->data_buf = kmalloc (sizeof(u_char) * (s3csmc_mtd->oobblock + s3csmc_mtd->oobsize), GFP_KERNEL); if (!this->data_buf) { printk ("Unable to allocate NAND data buffer for SMDK24A0.\n"); err = -ENOMEM; goto out_mtd; } /* Register the partitions */ switch(s3csmc_mtd->size){ case SZ_16M: add_mtd_partitions(s3csmc_mtd, partition_info16M, NUM_PARTITIONS16M); break; case SZ_32M: add_mtd_partitions(s3csmc_mtd, partition_info32M, NUM_PARTITIONS32M); break; case SZ_64M: add_mtd_partitions(s3csmc_mtd, partition_info64M, NUM_PARTITIONS64M); break; case SZ_128M: add_mtd_partitions(s3csmc_mtd, partition_info128M, NUM_PARTITIONS128M); break; default: { printk ("Unsupported SmartMedia device\n"); err = -ENXIO; goto out_cac; } } goto out; out_cac:out_buf: kfree (this->data_buf); out_mtd: kfree (s3csmc_mtd); out_ior:out: return err;}module_init(s3csmc_init); /* * Clean up routine */#ifdef MODULEstatic void __exit s3csmc_cleanup (void){ struct nand_chip *this = (struct nand_chip *) &s3csmc_mtd[1]; /* Unregister partitions */ del_mtd_partitions(s3csmc_mtd); /* Unregister the device */ del_mtd_device (s3csmc_mtd); /* Free internal data buffers */ kfree (this->data_buf); kfree (this->data_cache); /* Free the MTD device structure */ kfree (s3csmc_mtd);}module_exit(s3csmc_cleanup);#endif MODULE_LICENSE("GPL");MODULE_AUTHOR("Naushad <naushad@samsung.com>");MODULE_DESCRIPTION("Glue layer for NAND on SMDK24A0 board");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -