linux/drivers/mtd/nand/raw/ams-delta.c
<<
>>
Prefs
   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/nand-gpio.h>
  23#include <linux/mtd/rawnand.h>
  24#include <linux/mtd/partitions.h>
  25#include <linux/of_device.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        chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
 221
 222        if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 223                chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 224
 225        return 0;
 226}
 227
 228static const struct nand_controller_ops gpio_nand_ops = {
 229        .exec_op = gpio_nand_exec_op,
 230        .attach_chip = gpio_nand_attach_chip,
 231        .setup_interface = gpio_nand_setup_interface,
 232};
 233
 234/*
 235 * Main initialization routine
 236 */
 237static int gpio_nand_probe(struct platform_device *pdev)
 238{
 239        struct gpio_nand_platdata *pdata = dev_get_platdata(&pdev->dev);
 240        const struct mtd_partition *partitions = NULL;
 241        int num_partitions = 0;
 242        struct gpio_nand *priv;
 243        struct nand_chip *this;
 244        struct mtd_info *mtd;
 245        int (*probe)(struct platform_device *pdev, struct gpio_nand *priv);
 246        int err = 0;
 247
 248        if (pdata) {
 249                partitions = pdata->parts;
 250                num_partitions = pdata->num_parts;
 251        }
 252
 253        /* Allocate memory for MTD device structure and private data */
 254        priv = devm_kzalloc(&pdev->dev, sizeof(struct gpio_nand),
 255                            GFP_KERNEL);
 256        if (!priv)
 257                return -ENOMEM;
 258
 259        this = &priv->nand_chip;
 260
 261        mtd = nand_to_mtd(this);
 262        mtd->dev.parent = &pdev->dev;
 263
 264        nand_set_controller_data(this, priv);
 265        nand_set_flash_node(this, pdev->dev.of_node);
 266
 267        priv->gpiod_rdy = devm_gpiod_get_optional(&pdev->dev, "rdy", GPIOD_IN);
 268        if (IS_ERR(priv->gpiod_rdy)) {
 269                err = PTR_ERR(priv->gpiod_rdy);
 270                dev_warn(&pdev->dev, "RDY GPIO request failed (%d)\n", err);
 271                return err;
 272        }
 273
 274        platform_set_drvdata(pdev, priv);
 275
 276        /* Set chip enabled but write protected */
 277        priv->gpiod_nwp = devm_gpiod_get_optional(&pdev->dev, "nwp",
 278                                                  GPIOD_OUT_HIGH);
 279        if (IS_ERR(priv->gpiod_nwp)) {
 280                err = PTR_ERR(priv->gpiod_nwp);
 281                dev_err(&pdev->dev, "NWP GPIO request failed (%d)\n", err);
 282                return err;
 283        }
 284
 285        priv->gpiod_nce = devm_gpiod_get_optional(&pdev->dev, "nce",
 286                                                  GPIOD_OUT_LOW);
 287        if (IS_ERR(priv->gpiod_nce)) {
 288                err = PTR_ERR(priv->gpiod_nce);
 289                dev_err(&pdev->dev, "NCE GPIO request failed (%d)\n", err);
 290                return err;
 291        }
 292
 293        priv->gpiod_nre = devm_gpiod_get_optional(&pdev->dev, "nre",
 294                                                  GPIOD_OUT_LOW);
 295        if (IS_ERR(priv->gpiod_nre)) {
 296                err = PTR_ERR(priv->gpiod_nre);
 297                dev_err(&pdev->dev, "NRE GPIO request failed (%d)\n", err);
 298                return err;
 299        }
 300
 301        priv->gpiod_nwe = devm_gpiod_get_optional(&pdev->dev, "nwe",
 302                                                  GPIOD_OUT_LOW);
 303        if (IS_ERR(priv->gpiod_nwe)) {
 304                err = PTR_ERR(priv->gpiod_nwe);
 305                dev_err(&pdev->dev, "NWE GPIO request failed (%d)\n", err);
 306                return err;
 307        }
 308
 309        priv->gpiod_ale = devm_gpiod_get(&pdev->dev, "ale", GPIOD_OUT_LOW);
 310        if (IS_ERR(priv->gpiod_ale)) {
 311                err = PTR_ERR(priv->gpiod_ale);
 312                dev_err(&pdev->dev, "ALE GPIO request failed (%d)\n", err);
 313                return err;
 314        }
 315
 316        priv->gpiod_cle = devm_gpiod_get(&pdev->dev, "cle", GPIOD_OUT_LOW);
 317        if (IS_ERR(priv->gpiod_cle)) {
 318                err = PTR_ERR(priv->gpiod_cle);
 319                dev_err(&pdev->dev, "CLE GPIO request failed (%d)\n", err);
 320                return err;
 321        }
 322
 323        /* Request array of data pins, initialize them as input */
 324        priv->data_gpiods = devm_gpiod_get_array_optional(&pdev->dev, "data",
 325                                                          GPIOD_IN);
 326        if (IS_ERR(priv->data_gpiods)) {
 327                err = PTR_ERR(priv->data_gpiods);
 328                dev_err(&pdev->dev, "data GPIO request failed: %d\n", err);
 329                return err;
 330        }
 331        if (priv->data_gpiods) {
 332                if (!priv->gpiod_nwe) {
 333                        dev_err(&pdev->dev,
 334                                "mandatory NWE pin not provided by platform\n");
 335                        return -ENODEV;
 336                }
 337
 338                priv->io_read = gpio_nand_io_read;
 339                priv->io_write = gpio_nand_io_write;
 340                priv->data_in = true;
 341        }
 342
 343        if (pdev->id_entry)
 344                probe = (void *) pdev->id_entry->driver_data;
 345        else
 346                probe = of_device_get_match_data(&pdev->dev);
 347        if (probe)
 348                err = probe(pdev, priv);
 349        if (err)
 350                return err;
 351
 352        if (!priv->io_read || !priv->io_write) {
 353                dev_err(&pdev->dev, "incomplete device configuration\n");
 354                return -ENODEV;
 355        }
 356
 357        /* Initialize the NAND controller object embedded in gpio_nand. */
 358        priv->base.ops = &gpio_nand_ops;
 359        nand_controller_init(&priv->base);
 360        this->controller = &priv->base;
 361
 362        /*
 363         * FIXME: We should release write protection only after nand_scan() to
 364         * be on the safe side but we can't do that until we have a generic way
 365         * to assert/deassert WP from the core.  Even if the core shouldn't
 366         * write things in the nand_scan() path, it should have control on this
 367         * pin just in case we ever need to disable write protection during
 368         * chip detection/initialization.
 369         */
 370        /* Release write protection */
 371        gpiod_set_value(priv->gpiod_nwp, 0);
 372
 373        /* Scan to find existence of the device */
 374        err = nand_scan(this, 1);
 375        if (err)
 376                return err;
 377
 378        /* Register the partitions */
 379        err = mtd_device_register(mtd, partitions, num_partitions);
 380        if (err)
 381                goto err_nand_cleanup;
 382
 383        return 0;
 384
 385err_nand_cleanup:
 386        nand_cleanup(this);
 387
 388        return err;
 389}
 390
 391/*
 392 * Clean up routine
 393 */
 394static int gpio_nand_remove(struct platform_device *pdev)
 395{
 396        struct gpio_nand *priv = platform_get_drvdata(pdev);
 397        struct mtd_info *mtd = nand_to_mtd(&priv->nand_chip);
 398        int ret;
 399
 400        /* Apply write protection */
 401        gpiod_set_value(priv->gpiod_nwp, 1);
 402
 403        /* Unregister device */
 404        ret = mtd_device_unregister(mtd);
 405        WARN_ON(ret);
 406        nand_cleanup(mtd_to_nand(mtd));
 407
 408        return 0;
 409}
 410
 411#ifdef CONFIG_OF
 412static const struct of_device_id gpio_nand_of_id_table[] = {
 413        {
 414                /* sentinel */
 415        },
 416};
 417MODULE_DEVICE_TABLE(of, gpio_nand_of_id_table);
 418#endif
 419
 420static const struct platform_device_id gpio_nand_plat_id_table[] = {
 421        {
 422                .name   = "ams-delta-nand",
 423        }, {
 424                /* sentinel */
 425        },
 426};
 427MODULE_DEVICE_TABLE(platform, gpio_nand_plat_id_table);
 428
 429static struct platform_driver gpio_nand_driver = {
 430        .probe          = gpio_nand_probe,
 431        .remove         = gpio_nand_remove,
 432        .id_table       = gpio_nand_plat_id_table,
 433        .driver         = {
 434                .name   = "ams-delta-nand",
 435                .of_match_table = of_match_ptr(gpio_nand_of_id_table),
 436        },
 437};
 438
 439module_platform_driver(gpio_nand_driver);
 440
 441MODULE_LICENSE("GPL v2");
 442MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
 443MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)");
 444