1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li> 4 * 5 * Derived from drivers/mtd/nand/toto.c (removed in v2.6.28) 6 * Copyright (c) 2003 Texas Instruments 7 * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de> 8 * 9 * Converted to platform driver by Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> 10 * Partially stolen from plat_nand.c 11 * 12 * Overview: 13 * This is a device driver for the NAND flash device found on the 14 * Amstrad E3 (Delta). 15 */ 16 17 #include <linux/slab.h> 18 #include <linux/module.h> 19 #include <linux/delay.h> 20 #include <linux/gpio/consumer.h> 21 #include <linux/mtd/mtd.h> 22 #include <linux/mtd/rawnand.h> 23 #include <linux/mtd/partitions.h> 24 #include <linux/platform_device.h> 25 #include <linux/sizes.h> 26 27 /* 28 * MTD structure for E3 (Delta) 29 */ 30 struct ams_delta_nand { 31 struct nand_controller base; 32 struct nand_chip nand_chip; 33 struct gpio_desc *gpiod_rdy; 34 struct gpio_desc *gpiod_nce; 35 struct gpio_desc *gpiod_nre; 36 struct gpio_desc *gpiod_nwp; 37 struct gpio_desc *gpiod_nwe; 38 struct gpio_desc *gpiod_ale; 39 struct gpio_desc *gpiod_cle; 40 struct gpio_descs *data_gpiods; 41 bool data_in; 42 }; 43 44 /* 45 * Define partitions for flash devices 46 */ 47 48 static const struct mtd_partition partition_info[] = { 49 { .name = "Kernel", 50 .offset = 0, 51 .size = 3 * SZ_1M + SZ_512K }, 52 { .name = "u-boot", 53 .offset = 3 * SZ_1M + SZ_512K, 54 .size = SZ_256K }, 55 { .name = "u-boot params", 56 .offset = 3 * SZ_1M + SZ_512K + SZ_256K, 57 .size = SZ_256K }, 58 { .name = "Amstrad LDR", 59 .offset = 4 * SZ_1M, 60 .size = SZ_256K }, 61 { .name = "File system", 62 .offset = 4 * SZ_1M + 1 * SZ_256K, 63 .size = 27 * SZ_1M }, 64 { .name = "PBL reserved", 65 .offset = 32 * SZ_1M - 3 * SZ_256K, 66 .size = 3 * SZ_256K }, 67 }; 68 69 static void ams_delta_write_commit(struct ams_delta_nand *priv) 70 { 71 gpiod_set_value(priv->gpiod_nwe, 0); 72 ndelay(40); 73 gpiod_set_value(priv->gpiod_nwe, 1); 74 } 75 76 static void ams_delta_io_write(struct ams_delta_nand *priv, u8 byte) 77 { 78 struct gpio_descs *data_gpiods = priv->data_gpiods; 79 DECLARE_BITMAP(values, BITS_PER_TYPE(byte)) = { byte, }; 80 81 gpiod_set_raw_array_value(data_gpiods->ndescs, data_gpiods->desc, 82 data_gpiods->info, values); 83 84 ams_delta_write_commit(priv); 85 } 86 87 static void ams_delta_dir_output(struct ams_delta_nand *priv, u8 byte) 88 { 89 struct gpio_descs *data_gpiods = priv->data_gpiods; 90 DECLARE_BITMAP(values, BITS_PER_TYPE(byte)) = { byte, }; 91 int i; 92 93 for (i = 0; i < data_gpiods->ndescs; i++) 94 gpiod_direction_output_raw(data_gpiods->desc[i], 95 test_bit(i, values)); 96 97 ams_delta_write_commit(priv); 98 99 priv->data_in = false; 100 } 101 102 static u8 ams_delta_io_read(struct ams_delta_nand *priv) 103 { 104 u8 res; 105 struct gpio_descs *data_gpiods = priv->data_gpiods; 106 DECLARE_BITMAP(values, BITS_PER_TYPE(res)) = { 0, }; 107 108 gpiod_set_value(priv->gpiod_nre, 0); 109 ndelay(40); 110 111 gpiod_get_raw_array_value(data_gpiods->ndescs, data_gpiods->desc, 112 data_gpiods->info, values); 113 114 gpiod_set_value(priv->gpiod_nre, 1); 115 116 res = values[0]; 117 return res; 118 } 119 120 static void ams_delta_dir_input(struct ams_delta_nand *priv) 121 { 122 struct gpio_descs *data_gpiods = priv->data_gpiods; 123 int i; 124 125 for (i = 0; i < data_gpiods->ndescs; i++) 126 gpiod_direction_input(data_gpiods->desc[i]); 127 128 priv->data_in = true; 129 } 130 131 static void ams_delta_write_buf(struct ams_delta_nand *priv, const u8 *buf, 132 int len) 133 { 134 int i = 0; 135 136 if (len > 0 && priv->data_in) 137 ams_delta_dir_output(priv, buf[i++]); 138 139 while (i < len) 140 ams_delta_io_write(priv, buf[i++]); 141 } 142 143 static void ams_delta_read_buf(struct ams_delta_nand *priv, u8 *buf, int len) 144 { 145 int i; 146 147 if (!priv->data_in) 148 ams_delta_dir_input(priv); 149 150 for (i = 0; i < len; i++) 151 buf[i] = ams_delta_io_read(priv); 152 } 153 154 static void ams_delta_ctrl_cs(struct ams_delta_nand *priv, bool assert) 155 { 156 gpiod_set_value(priv->gpiod_nce, assert ? 0 : 1); 157 } 158 159 static int ams_delta_exec_op(struct nand_chip *this, 160 const struct nand_operation *op, bool check_only) 161 { 162 struct ams_delta_nand *priv = nand_get_controller_data(this); 163 const struct nand_op_instr *instr; 164 int ret = 0; 165 166 if (check_only) 167 return 0; 168 169 ams_delta_ctrl_cs(priv, 1); 170 171 for (instr = op->instrs; instr < op->instrs + op->ninstrs; instr++) { 172 switch (instr->type) { 173 case NAND_OP_CMD_INSTR: 174 gpiod_set_value(priv->gpiod_cle, 1); 175 ams_delta_write_buf(priv, &instr->ctx.cmd.opcode, 1); 176 gpiod_set_value(priv->gpiod_cle, 0); 177 break; 178 179 case NAND_OP_ADDR_INSTR: 180 gpiod_set_value(priv->gpiod_ale, 1); 181 ams_delta_write_buf(priv, instr->ctx.addr.addrs, 182 instr->ctx.addr.naddrs); 183 gpiod_set_value(priv->gpiod_ale, 0); 184 break; 185 186 case NAND_OP_DATA_IN_INSTR: 187 ams_delta_read_buf(priv, instr->ctx.data.buf.in, 188 instr->ctx.data.len); 189 break; 190 191 case NAND_OP_DATA_OUT_INSTR: 192 ams_delta_write_buf(priv, instr->ctx.data.buf.out, 193 instr->ctx.data.len); 194 break; 195 196 case NAND_OP_WAITRDY_INSTR: 197 ret = priv->gpiod_rdy ? 198 nand_gpio_waitrdy(this, priv->gpiod_rdy, 199 instr->ctx.waitrdy.timeout_ms) : 200 nand_soft_waitrdy(this, 201 instr->ctx.waitrdy.timeout_ms); 202 break; 203 } 204 205 if (ret) 206 break; 207 } 208 209 ams_delta_ctrl_cs(priv, 0); 210 211 return ret; 212 } 213 214 static const struct nand_controller_ops ams_delta_ops = { 215 .exec_op = ams_delta_exec_op, 216 }; 217 218 /* 219 * Main initialization routine 220 */ 221 static int ams_delta_init(struct platform_device *pdev) 222 { 223 struct ams_delta_nand *priv; 224 struct nand_chip *this; 225 struct mtd_info *mtd; 226 struct gpio_descs *data_gpiods; 227 int err = 0; 228 229 /* Allocate memory for MTD device structure and private data */ 230 priv = devm_kzalloc(&pdev->dev, sizeof(struct ams_delta_nand), 231 GFP_KERNEL); 232 if (!priv) 233 return -ENOMEM; 234 235 this = &priv->nand_chip; 236 237 mtd = nand_to_mtd(this); 238 mtd->dev.parent = &pdev->dev; 239 240 nand_set_controller_data(this, priv); 241 242 priv->gpiod_rdy = devm_gpiod_get_optional(&pdev->dev, "rdy", GPIOD_IN); 243 if (IS_ERR(priv->gpiod_rdy)) { 244 err = PTR_ERR(priv->gpiod_rdy); 245 dev_warn(&pdev->dev, "RDY GPIO request failed (%d)\n", err); 246 return err; 247 } 248 249 this->ecc.mode = NAND_ECC_SOFT; 250 this->ecc.algo = NAND_ECC_HAMMING; 251 252 platform_set_drvdata(pdev, priv); 253 254 /* Set chip enabled, but */ 255 priv->gpiod_nwp = devm_gpiod_get(&pdev->dev, "nwp", GPIOD_OUT_HIGH); 256 if (IS_ERR(priv->gpiod_nwp)) { 257 err = PTR_ERR(priv->gpiod_nwp); 258 dev_err(&pdev->dev, "NWP GPIO request failed (%d)\n", err); 259 return err; 260 } 261 262 priv->gpiod_nce = devm_gpiod_get(&pdev->dev, "nce", GPIOD_OUT_HIGH); 263 if (IS_ERR(priv->gpiod_nce)) { 264 err = PTR_ERR(priv->gpiod_nce); 265 dev_err(&pdev->dev, "NCE GPIO request failed (%d)\n", err); 266 return err; 267 } 268 269 priv->gpiod_nre = devm_gpiod_get(&pdev->dev, "nre", GPIOD_OUT_HIGH); 270 if (IS_ERR(priv->gpiod_nre)) { 271 err = PTR_ERR(priv->gpiod_nre); 272 dev_err(&pdev->dev, "NRE GPIO request failed (%d)\n", err); 273 return err; 274 } 275 276 priv->gpiod_nwe = devm_gpiod_get(&pdev->dev, "nwe", GPIOD_OUT_HIGH); 277 if (IS_ERR(priv->gpiod_nwe)) { 278 err = PTR_ERR(priv->gpiod_nwe); 279 dev_err(&pdev->dev, "NWE GPIO request failed (%d)\n", err); 280 return err; 281 } 282 283 priv->gpiod_ale = devm_gpiod_get(&pdev->dev, "ale", GPIOD_OUT_LOW); 284 if (IS_ERR(priv->gpiod_ale)) { 285 err = PTR_ERR(priv->gpiod_ale); 286 dev_err(&pdev->dev, "ALE GPIO request failed (%d)\n", err); 287 return err; 288 } 289 290 priv->gpiod_cle = devm_gpiod_get(&pdev->dev, "cle", GPIOD_OUT_LOW); 291 if (IS_ERR(priv->gpiod_cle)) { 292 err = PTR_ERR(priv->gpiod_cle); 293 dev_err(&pdev->dev, "CLE GPIO request failed (%d)\n", err); 294 return err; 295 } 296 297 /* Request array of data pins, initialize them as input */ 298 data_gpiods = devm_gpiod_get_array(&pdev->dev, "data", GPIOD_IN); 299 if (IS_ERR(data_gpiods)) { 300 err = PTR_ERR(data_gpiods); 301 dev_err(&pdev->dev, "data GPIO request failed: %d\n", err); 302 return err; 303 } 304 priv->data_gpiods = data_gpiods; 305 priv->data_in = true; 306 307 /* Initialize the NAND controller object embedded in ams_delta_nand. */ 308 priv->base.ops = &ams_delta_ops; 309 nand_controller_init(&priv->base); 310 this->controller = &priv->base; 311 312 /* Scan to find existence of the device */ 313 err = nand_scan(this, 1); 314 if (err) 315 return err; 316 317 /* Register the partitions */ 318 err = mtd_device_register(mtd, partition_info, 319 ARRAY_SIZE(partition_info)); 320 if (err) 321 goto err_nand_cleanup; 322 323 return 0; 324 325 err_nand_cleanup: 326 nand_cleanup(this); 327 328 return err; 329 } 330 331 /* 332 * Clean up routine 333 */ 334 static int ams_delta_cleanup(struct platform_device *pdev) 335 { 336 struct ams_delta_nand *priv = platform_get_drvdata(pdev); 337 struct mtd_info *mtd = nand_to_mtd(&priv->nand_chip); 338 339 /* Unregister device */ 340 nand_release(mtd_to_nand(mtd)); 341 342 return 0; 343 } 344 345 static struct platform_driver ams_delta_nand_driver = { 346 .probe = ams_delta_init, 347 .remove = ams_delta_cleanup, 348 .driver = { 349 .name = "ams-delta-nand", 350 }, 351 }; 352 353 module_platform_driver(ams_delta_nand_driver); 354 355 MODULE_LICENSE("GPL v2"); 356 MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>"); 357 MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)"); 358