87 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2022 Aidan MacDonald4 *5 * Author: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>6 */7 8#include <linux/device.h>9#include <linux/kernel.h>10#include <linux/mtd/spinand.h>11 12 13#define SPINAND_MFR_ATO 0x9b14 15 16static SPINAND_OP_VARIANTS(read_cache_variants,17 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),18 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),19 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));20 21static SPINAND_OP_VARIANTS(write_cache_variants,22 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),23 SPINAND_PROG_LOAD(true, 0, NULL, 0));24 25static SPINAND_OP_VARIANTS(update_cache_variants,26 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),27 SPINAND_PROG_LOAD(false, 0, NULL, 0));28 29 30static int ato25d1ga_ooblayout_ecc(struct mtd_info *mtd, int section,31 struct mtd_oob_region *region)32{33 if (section > 3)34 return -ERANGE;35 36 region->offset = (16 * section) + 8;37 region->length = 8;38 return 0;39}40 41static int ato25d1ga_ooblayout_free(struct mtd_info *mtd, int section,42 struct mtd_oob_region *region)43{44 if (section > 3)45 return -ERANGE;46 47 if (section) {48 region->offset = (16 * section);49 region->length = 8;50 } else {51 /* first byte of section 0 is reserved for the BBM */52 region->offset = 1;53 region->length = 7;54 }55 56 return 0;57}58 59static const struct mtd_ooblayout_ops ato25d1ga_ooblayout = {60 .ecc = ato25d1ga_ooblayout_ecc,61 .free = ato25d1ga_ooblayout_free,62};63 64 65static const struct spinand_info ato_spinand_table[] = {66 SPINAND_INFO("ATO25D1GA",67 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x12),68 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),69 NAND_ECCREQ(1, 512),70 SPINAND_INFO_OP_VARIANTS(&read_cache_variants,71 &write_cache_variants,72 &update_cache_variants),73 SPINAND_HAS_QE_BIT,74 SPINAND_ECCINFO(&ato25d1ga_ooblayout, NULL)),75};76 77static const struct spinand_manufacturer_ops ato_spinand_manuf_ops = {78};79 80const struct spinand_manufacturer ato_spinand_manufacturer = {81 .id = SPINAND_MFR_ATO,82 .name = "ATO",83 .chips = ato_spinand_table,84 .nchips = ARRAY_SIZE(ato_spinand_table),85 .ops = &ato_spinand_manuf_ops,86};87