linux/drivers/misc/eeprom/at25.c
<<
>>
Prefs
   1/*
   2 * at25.c -- support most SPI EEPROMs, such as Atmel AT25 models
   3 *
   4 * Copyright (C) 2006 David Brownell
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/init.h>
  14#include <linux/module.h>
  15#include <linux/slab.h>
  16#include <linux/delay.h>
  17#include <linux/device.h>
  18#include <linux/sched.h>
  19
  20#include <linux/spi/spi.h>
  21#include <linux/spi/eeprom.h>
  22
  23
  24/*
  25 * NOTE: this is an *EEPROM* driver.  The vagaries of product naming
  26 * mean that some AT25 products are EEPROMs, and others are FLASH.
  27 * Handle FLASH chips with the drivers/mtd/devices/m25p80.c driver,
  28 * not this one!
  29 */
  30
  31struct at25_data {
  32        struct spi_device       *spi;
  33        struct memory_accessor  mem;
  34        struct mutex            lock;
  35        struct spi_eeprom       chip;
  36        struct bin_attribute    bin;
  37        unsigned                addrlen;
  38};
  39
  40#define AT25_WREN       0x06            /* latch the write enable */
  41#define AT25_WRDI       0x04            /* reset the write enable */
  42#define AT25_RDSR       0x05            /* read status register */
  43#define AT25_WRSR       0x01            /* write status register */
  44#define AT25_READ       0x03            /* read byte(s) */
  45#define AT25_WRITE      0x02            /* write byte(s)/sector */
  46
  47#define AT25_SR_nRDY    0x01            /* nRDY = write-in-progress */
  48#define AT25_SR_WEN     0x02            /* write enable (latched) */
  49#define AT25_SR_BP0     0x04            /* BP for software writeprotect */
  50#define AT25_SR_BP1     0x08
  51#define AT25_SR_WPEN    0x80            /* writeprotect enable */
  52
  53
  54#define EE_MAXADDRLEN   3               /* 24 bit addresses, up to 2 MBytes */
  55
  56/* Specs often allow 5 msec for a page write, sometimes 20 msec;
  57 * it's important to recover from write timeouts.
  58 */
  59#define EE_TIMEOUT      25
  60
  61/*-------------------------------------------------------------------------*/
  62
  63#define io_limit        PAGE_SIZE       /* bytes */
  64
  65static ssize_t
  66at25_ee_read(
  67        struct at25_data        *at25,
  68        char                    *buf,
  69        unsigned                offset,
  70        size_t                  count
  71)
  72{
  73        u8                      command[EE_MAXADDRLEN + 1];
  74        u8                      *cp;
  75        ssize_t                 status;
  76        struct spi_transfer     t[2];
  77        struct spi_message      m;
  78
  79        if (unlikely(offset >= at25->bin.size))
  80                return 0;
  81        if ((offset + count) > at25->bin.size)
  82                count = at25->bin.size - offset;
  83        if (unlikely(!count))
  84                return count;
  85
  86        cp = command;
  87        *cp++ = AT25_READ;
  88
  89        /* 8/16/24-bit address is written MSB first */
  90        switch (at25->addrlen) {
  91        default:        /* case 3 */
  92                *cp++ = offset >> 16;
  93        case 2:
  94                *cp++ = offset >> 8;
  95        case 1:
  96        case 0: /* can't happen: for better codegen */
  97                *cp++ = offset >> 0;
  98        }
  99
 100        spi_message_init(&m);
 101        memset(t, 0, sizeof t);
 102
 103        t[0].tx_buf = command;
 104        t[0].len = at25->addrlen + 1;
 105        spi_message_add_tail(&t[0], &m);
 106
 107        t[1].rx_buf = buf;
 108        t[1].len = count;
 109        spi_message_add_tail(&t[1], &m);
 110
 111        mutex_lock(&at25->lock);
 112
 113        /* Read it all at once.
 114         *
 115         * REVISIT that's potentially a problem with large chips, if
 116         * other devices on the bus need to be accessed regularly or
 117         * this chip is clocked very slowly
 118         */
 119        status = spi_sync(at25->spi, &m);
 120        dev_dbg(&at25->spi->dev,
 121                "read %Zd bytes at %d --> %d\n",
 122                count, offset, (int) status);
 123
 124        mutex_unlock(&at25->lock);
 125        return status ? status : count;
 126}
 127
 128static ssize_t
 129at25_bin_read(struct file *filp, struct kobject *kobj,
 130              struct bin_attribute *bin_attr,
 131              char *buf, loff_t off, size_t count)
 132{
 133        struct device           *dev;
 134        struct at25_data        *at25;
 135
 136        dev = container_of(kobj, struct device, kobj);
 137        at25 = dev_get_drvdata(dev);
 138
 139        return at25_ee_read(at25, buf, off, count);
 140}
 141
 142
 143static ssize_t
 144at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
 145              size_t count)
 146{
 147        ssize_t                 status = 0;
 148        unsigned                written = 0;
 149        unsigned                buf_size;
 150        u8                      *bounce;
 151
 152        if (unlikely(off >= at25->bin.size))
 153                return -EFBIG;
 154        if ((off + count) > at25->bin.size)
 155                count = at25->bin.size - off;
 156        if (unlikely(!count))
 157                return count;
 158
 159        /* Temp buffer starts with command and address */
 160        buf_size = at25->chip.page_size;
 161        if (buf_size > io_limit)
 162                buf_size = io_limit;
 163        bounce = kmalloc(buf_size + at25->addrlen + 1, GFP_KERNEL);
 164        if (!bounce)
 165                return -ENOMEM;
 166
 167        /* For write, rollover is within the page ... so we write at
 168         * most one page, then manually roll over to the next page.
 169         */
 170        bounce[0] = AT25_WRITE;
 171        mutex_lock(&at25->lock);
 172        do {
 173                unsigned long   timeout, retries;
 174                unsigned        segment;
 175                unsigned        offset = (unsigned) off;
 176                u8              *cp = bounce + 1;
 177                int             sr;
 178
 179                *cp = AT25_WREN;
 180                status = spi_write(at25->spi, cp, 1);
 181                if (status < 0) {
 182                        dev_dbg(&at25->spi->dev, "WREN --> %d\n",
 183                                        (int) status);
 184                        break;
 185                }
 186
 187                /* 8/16/24-bit address is written MSB first */
 188                switch (at25->addrlen) {
 189                default:        /* case 3 */
 190                        *cp++ = offset >> 16;
 191                case 2:
 192                        *cp++ = offset >> 8;
 193                case 1:
 194                case 0: /* can't happen: for better codegen */
 195                        *cp++ = offset >> 0;
 196                }
 197
 198                /* Write as much of a page as we can */
 199                segment = buf_size - (offset % buf_size);
 200                if (segment > count)
 201                        segment = count;
 202                memcpy(cp, buf, segment);
 203                status = spi_write(at25->spi, bounce,
 204                                segment + at25->addrlen + 1);
 205                dev_dbg(&at25->spi->dev,
 206                                "write %u bytes at %u --> %d\n",
 207                                segment, offset, (int) status);
 208                if (status < 0)
 209                        break;
 210
 211                /* REVISIT this should detect (or prevent) failed writes
 212                 * to readonly sections of the EEPROM...
 213                 */
 214
 215                /* Wait for non-busy status */
 216                timeout = jiffies + msecs_to_jiffies(EE_TIMEOUT);
 217                retries = 0;
 218                do {
 219
 220                        sr = spi_w8r8(at25->spi, AT25_RDSR);
 221                        if (sr < 0 || (sr & AT25_SR_nRDY)) {
 222                                dev_dbg(&at25->spi->dev,
 223                                        "rdsr --> %d (%02x)\n", sr, sr);
 224                                /* at HZ=100, this is sloooow */
 225                                msleep(1);
 226                                continue;
 227                        }
 228                        if (!(sr & AT25_SR_nRDY))
 229                                break;
 230                } while (retries++ < 3 || time_before_eq(jiffies, timeout));
 231
 232                if ((sr < 0) || (sr & AT25_SR_nRDY)) {
 233                        dev_err(&at25->spi->dev,
 234                                "write %d bytes offset %d, "
 235                                "timeout after %u msecs\n",
 236                                segment, offset,
 237                                jiffies_to_msecs(jiffies -
 238                                        (timeout - EE_TIMEOUT)));
 239                        status = -ETIMEDOUT;
 240                        break;
 241                }
 242
 243                off += segment;
 244                buf += segment;
 245                count -= segment;
 246                written += segment;
 247
 248        } while (count > 0);
 249
 250        mutex_unlock(&at25->lock);
 251
 252        kfree(bounce);
 253        return written ? written : status;
 254}
 255
 256static ssize_t
 257at25_bin_write(struct file *filp, struct kobject *kobj,
 258               struct bin_attribute *bin_attr,
 259               char *buf, loff_t off, size_t count)
 260{
 261        struct device           *dev;
 262        struct at25_data        *at25;
 263
 264        dev = container_of(kobj, struct device, kobj);
 265        at25 = dev_get_drvdata(dev);
 266
 267        return at25_ee_write(at25, buf, off, count);
 268}
 269
 270/*-------------------------------------------------------------------------*/
 271
 272/* Let in-kernel code access the eeprom data. */
 273
 274static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf,
 275                         off_t offset, size_t count)
 276{
 277        struct at25_data *at25 = container_of(mem, struct at25_data, mem);
 278
 279        return at25_ee_read(at25, buf, offset, count);
 280}
 281
 282static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
 283                          off_t offset, size_t count)
 284{
 285        struct at25_data *at25 = container_of(mem, struct at25_data, mem);
 286
 287        return at25_ee_write(at25, buf, offset, count);
 288}
 289
 290/*-------------------------------------------------------------------------*/
 291
 292static int at25_probe(struct spi_device *spi)
 293{
 294        struct at25_data        *at25 = NULL;
 295        const struct spi_eeprom *chip;
 296        int                     err;
 297        int                     sr;
 298        int                     addrlen;
 299
 300        /* Chip description */
 301        chip = spi->dev.platform_data;
 302        if (!chip) {
 303                dev_dbg(&spi->dev, "no chip description\n");
 304                err = -ENODEV;
 305                goto fail;
 306        }
 307
 308        /* For now we only support 8/16/24 bit addressing */
 309        if (chip->flags & EE_ADDR1)
 310                addrlen = 1;
 311        else if (chip->flags & EE_ADDR2)
 312                addrlen = 2;
 313        else if (chip->flags & EE_ADDR3)
 314                addrlen = 3;
 315        else {
 316                dev_dbg(&spi->dev, "unsupported address type\n");
 317                err = -EINVAL;
 318                goto fail;
 319        }
 320
 321        /* Ping the chip ... the status register is pretty portable,
 322         * unlike probing manufacturer IDs.  We do expect that system
 323         * firmware didn't write it in the past few milliseconds!
 324         */
 325        sr = spi_w8r8(spi, AT25_RDSR);
 326        if (sr < 0 || sr & AT25_SR_nRDY) {
 327                dev_dbg(&spi->dev, "rdsr --> %d (%02x)\n", sr, sr);
 328                err = -ENXIO;
 329                goto fail;
 330        }
 331
 332        if (!(at25 = kzalloc(sizeof *at25, GFP_KERNEL))) {
 333                err = -ENOMEM;
 334                goto fail;
 335        }
 336
 337        mutex_init(&at25->lock);
 338        at25->chip = *chip;
 339        at25->spi = spi_dev_get(spi);
 340        dev_set_drvdata(&spi->dev, at25);
 341        at25->addrlen = addrlen;
 342
 343        /* Export the EEPROM bytes through sysfs, since that's convenient.
 344         * And maybe to other kernel code; it might hold a board's Ethernet
 345         * address, or board-specific calibration data generated on the
 346         * manufacturing floor.
 347         *
 348         * Default to root-only access to the data; EEPROMs often hold data
 349         * that's sensitive for read and/or write, like ethernet addresses,
 350         * security codes, board-specific manufacturing calibrations, etc.
 351         */
 352        sysfs_bin_attr_init(&at25->bin);
 353        at25->bin.attr.name = "eeprom";
 354        at25->bin.attr.mode = S_IRUSR;
 355        at25->bin.read = at25_bin_read;
 356        at25->mem.read = at25_mem_read;
 357
 358        at25->bin.size = at25->chip.byte_len;
 359        if (!(chip->flags & EE_READONLY)) {
 360                at25->bin.write = at25_bin_write;
 361                at25->bin.attr.mode |= S_IWUSR;
 362                at25->mem.write = at25_mem_write;
 363        }
 364
 365        err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin);
 366        if (err)
 367                goto fail;
 368
 369        if (chip->setup)
 370                chip->setup(&at25->mem, chip->context);
 371
 372        dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
 373                (at25->bin.size < 1024)
 374                        ? at25->bin.size
 375                        : (at25->bin.size / 1024),
 376                (at25->bin.size < 1024) ? "Byte" : "KByte",
 377                at25->chip.name,
 378                (chip->flags & EE_READONLY) ? " (readonly)" : "",
 379                at25->chip.page_size);
 380        return 0;
 381fail:
 382        dev_dbg(&spi->dev, "probe err %d\n", err);
 383        kfree(at25);
 384        return err;
 385}
 386
 387static int __devexit at25_remove(struct spi_device *spi)
 388{
 389        struct at25_data        *at25;
 390
 391        at25 = dev_get_drvdata(&spi->dev);
 392        sysfs_remove_bin_file(&spi->dev.kobj, &at25->bin);
 393        kfree(at25);
 394        return 0;
 395}
 396
 397/*-------------------------------------------------------------------------*/
 398
 399static struct spi_driver at25_driver = {
 400        .driver = {
 401                .name           = "at25",
 402                .owner          = THIS_MODULE,
 403        },
 404        .probe          = at25_probe,
 405        .remove         = __devexit_p(at25_remove),
 406};
 407
 408static int __init at25_init(void)
 409{
 410        return spi_register_driver(&at25_driver);
 411}
 412module_init(at25_init);
 413
 414static void __exit at25_exit(void)
 415{
 416        spi_unregister_driver(&at25_driver);
 417}
 418module_exit(at25_exit);
 419
 420MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
 421MODULE_AUTHOR("David Brownell");
 422MODULE_LICENSE("GPL");
 423MODULE_ALIAS("spi:at25");
 424