448 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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 Instruments7 * 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.c11 *12 * Overview:13 * This is a device driver for the NAND flash device found on the14 * 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/nand-gpio.h>23#include <linux/mtd/rawnand.h>24#include <linux/mtd/partitions.h>25#include <linux/of.h>26#include <linux/platform_device.h>27#include <linux/sizes.h>28 29/*30 * MTD structure for E3 (Delta)31 */32struct gpio_nand {33 struct nand_controller base;34 struct nand_chip nand_chip;35 struct gpio_desc *gpiod_rdy;36 struct gpio_desc *gpiod_nce;37 struct gpio_desc *gpiod_nre;38 struct gpio_desc *gpiod_nwp;39 struct gpio_desc *gpiod_nwe;40 struct gpio_desc *gpiod_ale;41 struct gpio_desc *gpiod_cle;42 struct gpio_descs *data_gpiods;43 bool data_in;44 unsigned int tRP;45 unsigned int tWP;46 u8 (*io_read)(struct gpio_nand *this);47 void (*io_write)(struct gpio_nand *this, u8 byte);48};49 50static void gpio_nand_write_commit(struct gpio_nand *priv)51{52 gpiod_set_value(priv->gpiod_nwe, 1);53 ndelay(priv->tWP);54 gpiod_set_value(priv->gpiod_nwe, 0);55}56 57static void gpio_nand_io_write(struct gpio_nand *priv, u8 byte)58{59 struct gpio_descs *data_gpiods = priv->data_gpiods;60 DECLARE_BITMAP(values, BITS_PER_TYPE(byte)) = { byte, };61 62 gpiod_set_raw_array_value(data_gpiods->ndescs, data_gpiods->desc,63 data_gpiods->info, values);64 65 gpio_nand_write_commit(priv);66}67 68static void gpio_nand_dir_output(struct gpio_nand *priv, u8 byte)69{70 struct gpio_descs *data_gpiods = priv->data_gpiods;71 DECLARE_BITMAP(values, BITS_PER_TYPE(byte)) = { byte, };72 int i;73 74 for (i = 0; i < data_gpiods->ndescs; i++)75 gpiod_direction_output_raw(data_gpiods->desc[i],76 test_bit(i, values));77 78 gpio_nand_write_commit(priv);79 80 priv->data_in = false;81}82 83static u8 gpio_nand_io_read(struct gpio_nand *priv)84{85 u8 res;86 struct gpio_descs *data_gpiods = priv->data_gpiods;87 DECLARE_BITMAP(values, BITS_PER_TYPE(res)) = { 0, };88 89 gpiod_set_value(priv->gpiod_nre, 1);90 ndelay(priv->tRP);91 92 gpiod_get_raw_array_value(data_gpiods->ndescs, data_gpiods->desc,93 data_gpiods->info, values);94 95 gpiod_set_value(priv->gpiod_nre, 0);96 97 res = values[0];98 return res;99}100 101static void gpio_nand_dir_input(struct gpio_nand *priv)102{103 struct gpio_descs *data_gpiods = priv->data_gpiods;104 int i;105 106 for (i = 0; i < data_gpiods->ndescs; i++)107 gpiod_direction_input(data_gpiods->desc[i]);108 109 priv->data_in = true;110}111 112static void gpio_nand_write_buf(struct gpio_nand *priv, const u8 *buf, int len)113{114 int i = 0;115 116 if (len > 0 && priv->data_in)117 gpio_nand_dir_output(priv, buf[i++]);118 119 while (i < len)120 priv->io_write(priv, buf[i++]);121}122 123static void gpio_nand_read_buf(struct gpio_nand *priv, u8 *buf, int len)124{125 int i;126 127 if (priv->data_gpiods && !priv->data_in)128 gpio_nand_dir_input(priv);129 130 for (i = 0; i < len; i++)131 buf[i] = priv->io_read(priv);132}133 134static void gpio_nand_ctrl_cs(struct gpio_nand *priv, bool assert)135{136 gpiod_set_value(priv->gpiod_nce, assert);137}138 139static int gpio_nand_exec_op(struct nand_chip *this,140 const struct nand_operation *op, bool check_only)141{142 struct gpio_nand *priv = nand_get_controller_data(this);143 const struct nand_op_instr *instr;144 int ret = 0;145 146 if (check_only)147 return 0;148 149 gpio_nand_ctrl_cs(priv, 1);150 151 for (instr = op->instrs; instr < op->instrs + op->ninstrs; instr++) {152 switch (instr->type) {153 case NAND_OP_CMD_INSTR:154 gpiod_set_value(priv->gpiod_cle, 1);155 gpio_nand_write_buf(priv, &instr->ctx.cmd.opcode, 1);156 gpiod_set_value(priv->gpiod_cle, 0);157 break;158 159 case NAND_OP_ADDR_INSTR:160 gpiod_set_value(priv->gpiod_ale, 1);161 gpio_nand_write_buf(priv, instr->ctx.addr.addrs,162 instr->ctx.addr.naddrs);163 gpiod_set_value(priv->gpiod_ale, 0);164 break;165 166 case NAND_OP_DATA_IN_INSTR:167 gpio_nand_read_buf(priv, instr->ctx.data.buf.in,168 instr->ctx.data.len);169 break;170 171 case NAND_OP_DATA_OUT_INSTR:172 gpio_nand_write_buf(priv, instr->ctx.data.buf.out,173 instr->ctx.data.len);174 break;175 176 case NAND_OP_WAITRDY_INSTR:177 ret = priv->gpiod_rdy ?178 nand_gpio_waitrdy(this, priv->gpiod_rdy,179 instr->ctx.waitrdy.timeout_ms) :180 nand_soft_waitrdy(this,181 instr->ctx.waitrdy.timeout_ms);182 break;183 }184 185 if (ret)186 break;187 }188 189 gpio_nand_ctrl_cs(priv, 0);190 191 return ret;192}193 194static int gpio_nand_setup_interface(struct nand_chip *this, int csline,195 const struct nand_interface_config *cf)196{197 struct gpio_nand *priv = nand_get_controller_data(this);198 const struct nand_sdr_timings *sdr = nand_get_sdr_timings(cf);199 struct device *dev = &nand_to_mtd(this)->dev;200 201 if (IS_ERR(sdr))202 return PTR_ERR(sdr);203 204 if (csline == NAND_DATA_IFACE_CHECK_ONLY)205 return 0;206 207 if (priv->gpiod_nre) {208 priv->tRP = DIV_ROUND_UP(sdr->tRP_min, 1000);209 dev_dbg(dev, "using %u ns read pulse width\n", priv->tRP);210 }211 212 priv->tWP = DIV_ROUND_UP(sdr->tWP_min, 1000);213 dev_dbg(dev, "using %u ns write pulse width\n", priv->tWP);214 215 return 0;216}217 218static int gpio_nand_attach_chip(struct nand_chip *chip)219{220 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&221 chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)222 chip->ecc.algo = NAND_ECC_ALGO_HAMMING;223 224 return 0;225}226 227static const struct nand_controller_ops gpio_nand_ops = {228 .exec_op = gpio_nand_exec_op,229 .attach_chip = gpio_nand_attach_chip,230 .setup_interface = gpio_nand_setup_interface,231};232 233/*234 * Main initialization routine235 */236static int gpio_nand_probe(struct platform_device *pdev)237{238 struct gpio_nand_platdata *pdata = dev_get_platdata(&pdev->dev);239 const struct mtd_partition *partitions = NULL;240 int num_partitions = 0;241 struct gpio_nand *priv;242 struct nand_chip *this;243 struct mtd_info *mtd;244 int (*probe)(struct platform_device *pdev, struct gpio_nand *priv);245 int err = 0;246 247 if (pdata) {248 partitions = pdata->parts;249 num_partitions = pdata->num_parts;250 }251 252 /* Allocate memory for MTD device structure and private data */253 priv = devm_kzalloc(&pdev->dev, sizeof(struct gpio_nand),254 GFP_KERNEL);255 if (!priv)256 return -ENOMEM;257 258 this = &priv->nand_chip;259 260 mtd = nand_to_mtd(this);261 mtd->dev.parent = &pdev->dev;262 263 nand_set_controller_data(this, priv);264 nand_set_flash_node(this, pdev->dev.of_node);265 266 priv->gpiod_rdy = devm_gpiod_get_optional(&pdev->dev, "rdy", GPIOD_IN);267 if (IS_ERR(priv->gpiod_rdy)) {268 err = PTR_ERR(priv->gpiod_rdy);269 dev_warn(&pdev->dev, "RDY GPIO request failed (%d)\n", err);270 return err;271 }272 273 platform_set_drvdata(pdev, priv);274 275 /* Set chip enabled but write protected */276 priv->gpiod_nwp = devm_gpiod_get_optional(&pdev->dev, "nwp",277 GPIOD_OUT_HIGH);278 if (IS_ERR(priv->gpiod_nwp)) {279 err = PTR_ERR(priv->gpiod_nwp);280 dev_err(&pdev->dev, "NWP GPIO request failed (%d)\n", err);281 return err;282 }283 284 priv->gpiod_nce = devm_gpiod_get_optional(&pdev->dev, "nce",285 GPIOD_OUT_LOW);286 if (IS_ERR(priv->gpiod_nce)) {287 err = PTR_ERR(priv->gpiod_nce);288 dev_err(&pdev->dev, "NCE GPIO request failed (%d)\n", err);289 return err;290 }291 292 priv->gpiod_nre = devm_gpiod_get_optional(&pdev->dev, "nre",293 GPIOD_OUT_LOW);294 if (IS_ERR(priv->gpiod_nre)) {295 err = PTR_ERR(priv->gpiod_nre);296 dev_err(&pdev->dev, "NRE GPIO request failed (%d)\n", err);297 return err;298 }299 300 priv->gpiod_nwe = devm_gpiod_get_optional(&pdev->dev, "nwe",301 GPIOD_OUT_LOW);302 if (IS_ERR(priv->gpiod_nwe)) {303 err = PTR_ERR(priv->gpiod_nwe);304 dev_err(&pdev->dev, "NWE GPIO request failed (%d)\n", err);305 return err;306 }307 308 priv->gpiod_ale = devm_gpiod_get(&pdev->dev, "ale", GPIOD_OUT_LOW);309 if (IS_ERR(priv->gpiod_ale)) {310 err = PTR_ERR(priv->gpiod_ale);311 dev_err(&pdev->dev, "ALE GPIO request failed (%d)\n", err);312 return err;313 }314 315 priv->gpiod_cle = devm_gpiod_get(&pdev->dev, "cle", GPIOD_OUT_LOW);316 if (IS_ERR(priv->gpiod_cle)) {317 err = PTR_ERR(priv->gpiod_cle);318 dev_err(&pdev->dev, "CLE GPIO request failed (%d)\n", err);319 return err;320 }321 322 /* Request array of data pins, initialize them as input */323 priv->data_gpiods = devm_gpiod_get_array_optional(&pdev->dev, "data",324 GPIOD_IN);325 if (IS_ERR(priv->data_gpiods)) {326 err = PTR_ERR(priv->data_gpiods);327 dev_err(&pdev->dev, "data GPIO request failed: %d\n", err);328 return err;329 }330 if (priv->data_gpiods) {331 if (!priv->gpiod_nwe) {332 dev_err(&pdev->dev,333 "mandatory NWE pin not provided by platform\n");334 return -ENODEV;335 }336 337 priv->io_read = gpio_nand_io_read;338 priv->io_write = gpio_nand_io_write;339 priv->data_in = true;340 }341 342 if (pdev->id_entry)343 probe = (void *) pdev->id_entry->driver_data;344 else345 probe = of_device_get_match_data(&pdev->dev);346 if (probe)347 err = probe(pdev, priv);348 if (err)349 return err;350 351 if (!priv->io_read || !priv->io_write) {352 dev_err(&pdev->dev, "incomplete device configuration\n");353 return -ENODEV;354 }355 356 /* Initialize the NAND controller object embedded in gpio_nand. */357 priv->base.ops = &gpio_nand_ops;358 nand_controller_init(&priv->base);359 this->controller = &priv->base;360 361 /*362 * FIXME: We should release write protection only after nand_scan() to363 * be on the safe side but we can't do that until we have a generic way364 * to assert/deassert WP from the core. Even if the core shouldn't365 * write things in the nand_scan() path, it should have control on this366 * pin just in case we ever need to disable write protection during367 * chip detection/initialization.368 */369 /* Release write protection */370 gpiod_set_value(priv->gpiod_nwp, 0);371 372 /*373 * This driver assumes that the default ECC engine should be TYPE_SOFT.374 * Set ->engine_type before registering the NAND devices in order to375 * provide a driver specific default value.376 */377 this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;378 379 /* Scan to find existence of the device */380 err = nand_scan(this, 1);381 if (err)382 return err;383 384 /* Register the partitions */385 err = mtd_device_register(mtd, partitions, num_partitions);386 if (err)387 goto err_nand_cleanup;388 389 return 0;390 391err_nand_cleanup:392 nand_cleanup(this);393 394 return err;395}396 397/*398 * Clean up routine399 */400static void gpio_nand_remove(struct platform_device *pdev)401{402 struct gpio_nand *priv = platform_get_drvdata(pdev);403 struct mtd_info *mtd = nand_to_mtd(&priv->nand_chip);404 int ret;405 406 /* Apply write protection */407 gpiod_set_value(priv->gpiod_nwp, 1);408 409 /* Unregister device */410 ret = mtd_device_unregister(mtd);411 WARN_ON(ret);412 nand_cleanup(mtd_to_nand(mtd));413}414 415#ifdef CONFIG_OF416static const struct of_device_id gpio_nand_of_id_table[] = {417 {418 /* sentinel */419 },420};421MODULE_DEVICE_TABLE(of, gpio_nand_of_id_table);422#endif423 424static const struct platform_device_id gpio_nand_plat_id_table[] = {425 {426 .name = "ams-delta-nand",427 }, {428 /* sentinel */429 },430};431MODULE_DEVICE_TABLE(platform, gpio_nand_plat_id_table);432 433static struct platform_driver gpio_nand_driver = {434 .probe = gpio_nand_probe,435 .remove_new = gpio_nand_remove,436 .id_table = gpio_nand_plat_id_table,437 .driver = {438 .name = "ams-delta-nand",439 .of_match_table = of_match_ptr(gpio_nand_of_id_table),440 },441};442 443module_platform_driver(gpio_nand_driver);444 445MODULE_LICENSE("GPL v2");446MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");447MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)");448