0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/device.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mtd/spinand.h>
0011
0012
0013 #define SPINAND_MFR_ATO 0x9b
0014
0015
0016 static SPINAND_OP_VARIANTS(read_cache_variants,
0017 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
0018 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
0019 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
0020
0021 static SPINAND_OP_VARIANTS(write_cache_variants,
0022 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
0023 SPINAND_PROG_LOAD(true, 0, NULL, 0));
0024
0025 static SPINAND_OP_VARIANTS(update_cache_variants,
0026 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
0027 SPINAND_PROG_LOAD(false, 0, NULL, 0));
0028
0029
0030 static int ato25d1ga_ooblayout_ecc(struct mtd_info *mtd, int section,
0031 struct mtd_oob_region *region)
0032 {
0033 if (section > 3)
0034 return -ERANGE;
0035
0036 region->offset = (16 * section) + 8;
0037 region->length = 8;
0038 return 0;
0039 }
0040
0041 static int ato25d1ga_ooblayout_free(struct mtd_info *mtd, int section,
0042 struct mtd_oob_region *region)
0043 {
0044 if (section > 3)
0045 return -ERANGE;
0046
0047 if (section) {
0048 region->offset = (16 * section);
0049 region->length = 8;
0050 } else {
0051
0052 region->offset = 1;
0053 region->length = 7;
0054 }
0055
0056 return 0;
0057 }
0058
0059 static const struct mtd_ooblayout_ops ato25d1ga_ooblayout = {
0060 .ecc = ato25d1ga_ooblayout_ecc,
0061 .free = ato25d1ga_ooblayout_free,
0062 };
0063
0064
0065 static const struct spinand_info ato_spinand_table[] = {
0066 SPINAND_INFO("ATO25D1GA",
0067 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x12),
0068 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
0069 NAND_ECCREQ(1, 512),
0070 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0071 &write_cache_variants,
0072 &update_cache_variants),
0073 SPINAND_HAS_QE_BIT,
0074 SPINAND_ECCINFO(&ato25d1ga_ooblayout, NULL)),
0075 };
0076
0077 static const struct spinand_manufacturer_ops ato_spinand_manuf_ops = {
0078 };
0079
0080 const struct spinand_manufacturer ato_spinand_manufacturer = {
0081 .id = SPINAND_MFR_ATO,
0082 .name = "ATO",
0083 .chips = ato_spinand_table,
0084 .nchips = ARRAY_SIZE(ato_spinand_table),
0085 .ops = &ato_spinand_manuf_ops,
0086 };