uboot/common/cmd_eeprom.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000, 2001
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 *
  23 */
  24
  25/*
  26 * Support for read and write access to EEPROM like memory devices. This
  27 * includes regular EEPROM as well as  FRAM (ferroelectic nonvolaile RAM).
  28 * FRAM devices read and write data at bus speed. In particular, there is no
  29 * write delay. Also, there is no limit imposed on the numer of bytes that can
  30 * be transferred with a single read or write.
  31 *
  32 * Use the following configuration options to ensure no unneeded performance
  33 * degradation (typical for EEPROM) is incured for FRAM memory:
  34 *
  35 * #define CONFIG_SYS_I2C_FRAM
  36 * #undef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS
  37 *
  38 */
  39
  40#include <common.h>
  41#include <config.h>
  42#include <command.h>
  43#include <i2c.h>
  44
  45extern void eeprom_init  (void);
  46extern int  eeprom_read  (unsigned dev_addr, unsigned offset,
  47                          uchar *buffer, unsigned cnt);
  48extern int  eeprom_write (unsigned dev_addr, unsigned offset,
  49                          uchar *buffer, unsigned cnt);
  50#if defined(CONFIG_SYS_EEPROM_WREN)
  51extern int eeprom_write_enable (unsigned dev_addr, int state);
  52#endif
  53
  54
  55#if defined(CONFIG_SYS_EEPROM_X40430)
  56        /* Maximum number of times to poll for acknowledge after write */
  57#define MAX_ACKNOWLEDGE_POLLS   10
  58#endif
  59
  60/* ------------------------------------------------------------------------- */
  61
  62#if defined(CONFIG_CMD_EEPROM)
  63int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
  64{
  65        const char *const fmt =
  66                "\nEEPROM @0x%lX %s: addr %08lx  off %04lx  count %ld ... ";
  67
  68#if defined(CONFIG_SYS_I2C_MULTI_EEPROMS)
  69        if (argc == 6) {
  70                ulong dev_addr = simple_strtoul (argv[2], NULL, 16);
  71                ulong addr = simple_strtoul (argv[3], NULL, 16);
  72                ulong off  = simple_strtoul (argv[4], NULL, 16);
  73                ulong cnt  = simple_strtoul (argv[5], NULL, 16);
  74#else
  75        if (argc == 5) {
  76                ulong dev_addr = CONFIG_SYS_DEF_EEPROM_ADDR;
  77                ulong addr = simple_strtoul (argv[2], NULL, 16);
  78                ulong off  = simple_strtoul (argv[3], NULL, 16);
  79                ulong cnt  = simple_strtoul (argv[4], NULL, 16);
  80#endif /* CONFIG_SYS_I2C_MULTI_EEPROMS */
  81
  82# if !defined(CONFIG_SPI) || defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
  83                eeprom_init ();
  84# endif /* !CONFIG_SPI */
  85
  86                if (strcmp (argv[1], "read") == 0) {
  87                        int rcode;
  88
  89                        printf (fmt, dev_addr, argv[1], addr, off, cnt);
  90
  91                        rcode = eeprom_read (dev_addr, off, (uchar *) addr, cnt);
  92
  93                        puts ("done\n");
  94                        return rcode;
  95                } else if (strcmp (argv[1], "write") == 0) {
  96                        int rcode;
  97
  98                        printf (fmt, dev_addr, argv[1], addr, off, cnt);
  99
 100                        rcode = eeprom_write (dev_addr, off, (uchar *) addr, cnt);
 101
 102                        puts ("done\n");
 103                        return rcode;
 104                }
 105        }
 106
 107        return cmd_usage(cmdtp);
 108}
 109#endif
 110
 111/*-----------------------------------------------------------------------
 112 *
 113 * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is
 114 *   0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
 115 *
 116 * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is
 117 *   0x00000nxx for EEPROM address selectors and page number at n.
 118 */
 119
 120#if !defined(CONFIG_SPI) || defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
 121#if !defined(CONFIG_SYS_I2C_EEPROM_ADDR_LEN) || CONFIG_SYS_I2C_EEPROM_ADDR_LEN < 1 || CONFIG_SYS_I2C_EEPROM_ADDR_LEN > 2
 122#error CONFIG_SYS_I2C_EEPROM_ADDR_LEN must be 1 or 2
 123#endif
 124#endif
 125
 126int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt)
 127{
 128        unsigned end = offset + cnt;
 129        unsigned blk_off;
 130        int rcode = 0;
 131
 132        /* Read data until done or would cross a page boundary.
 133         * We must write the address again when changing pages
 134         * because the next page may be in a different device.
 135         */
 136        while (offset < end) {
 137                unsigned alen, len;
 138#if !defined(CONFIG_SYS_I2C_FRAM)
 139                unsigned maxlen;
 140#endif
 141
 142#if CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
 143                uchar addr[2];
 144
 145                blk_off = offset & 0xFF;        /* block offset */
 146
 147                addr[0] = offset >> 8;          /* block number */
 148                addr[1] = blk_off;              /* block offset */
 149                alen    = 2;
 150#else
 151                uchar addr[3];
 152
 153                blk_off = offset & 0xFF;        /* block offset */
 154
 155                addr[0] = offset >> 16;         /* block number */
 156                addr[1] = offset >>  8;         /* upper address octet */
 157                addr[2] = blk_off;              /* lower address octet */
 158                alen    = 3;
 159#endif  /* CONFIG_SYS_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */
 160
 161                addr[0] |= dev_addr;            /* insert device address */
 162
 163                len = end - offset;
 164
 165                /*
 166                 * For a FRAM device there is no limit on the number of the
 167                 * bytes that can be ccessed with the single read or write
 168                 * operation.
 169                 */
 170#if !defined(CONFIG_SYS_I2C_FRAM)
 171                maxlen = 0x100 - blk_off;
 172                if (maxlen > I2C_RXTX_LEN)
 173                        maxlen = I2C_RXTX_LEN;
 174                if (len > maxlen)
 175                        len = maxlen;
 176#endif
 177
 178#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
 179                spi_read (addr, alen, buffer, len);
 180#else
 181                if (i2c_read (addr[0], offset, alen-1, buffer, len) != 0)
 182                        rcode = 1;
 183#endif
 184                buffer += len;
 185                offset += len;
 186        }
 187
 188        return rcode;
 189}
 190
 191/*-----------------------------------------------------------------------
 192 *
 193 * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is
 194 *   0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
 195 *
 196 * for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is
 197 *   0x00000nxx for EEPROM address selectors and page number at n.
 198 */
 199
 200int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt)
 201{
 202        unsigned end = offset + cnt;
 203        unsigned blk_off;
 204        int rcode = 0;
 205
 206#if defined(CONFIG_SYS_EEPROM_X40430)
 207        uchar   contr_r_addr[2];
 208        uchar   addr_void[2];
 209        uchar   contr_reg[2];
 210        uchar   ctrl_reg_v;
 211        int     i;
 212#endif
 213
 214#if defined(CONFIG_SYS_EEPROM_WREN)
 215        eeprom_write_enable (dev_addr,1);
 216#endif
 217        /* Write data until done or would cross a write page boundary.
 218         * We must write the address again when changing pages
 219         * because the address counter only increments within a page.
 220         */
 221
 222        while (offset < end) {
 223                unsigned alen, len;
 224#if !defined(CONFIG_SYS_I2C_FRAM)
 225                unsigned maxlen;
 226#endif
 227
 228#if CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
 229                uchar addr[2];
 230
 231                blk_off = offset & 0xFF;        /* block offset */
 232
 233                addr[0] = offset >> 8;          /* block number */
 234                addr[1] = blk_off;              /* block offset */
 235                alen    = 2;
 236#else
 237                uchar addr[3];
 238
 239                blk_off = offset & 0xFF;        /* block offset */
 240
 241                addr[0] = offset >> 16;         /* block number */
 242                addr[1] = offset >>  8;         /* upper address octet */
 243                addr[2] = blk_off;              /* lower address octet */
 244                alen    = 3;
 245#endif  /* CONFIG_SYS_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */
 246
 247                addr[0] |= dev_addr;            /* insert device address */
 248
 249                len = end - offset;
 250
 251                /*
 252                 * For a FRAM device there is no limit on the number of the
 253                 * bytes that can be accessed with the single read or write
 254                 * operation.
 255                 */
 256#if !defined(CONFIG_SYS_I2C_FRAM)
 257
 258#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)
 259
 260#define EEPROM_PAGE_SIZE        (1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)
 261#define EEPROM_PAGE_OFFSET(x)   ((x) & (EEPROM_PAGE_SIZE - 1))
 262
 263                maxlen = EEPROM_PAGE_SIZE - EEPROM_PAGE_OFFSET(blk_off);
 264#else
 265                maxlen = 0x100 - blk_off;
 266#endif
 267                if (maxlen > I2C_RXTX_LEN)
 268                        maxlen = I2C_RXTX_LEN;
 269
 270                if (len > maxlen)
 271                        len = maxlen;
 272#endif
 273
 274#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
 275                spi_write (addr, alen, buffer, len);
 276#else
 277#if defined(CONFIG_SYS_EEPROM_X40430)
 278                /* Get the value of the control register.
 279                 * Set current address (internal pointer in the x40430)
 280                 * to 0x1ff.
 281                 */
 282                contr_r_addr[0] = 9;
 283                contr_r_addr[1] = 0xff;
 284                addr_void[0]    = 0;
 285                addr_void[1]    = addr[1];
 286#ifdef CONFIG_SYS_I2C_EEPROM_ADDR
 287                contr_r_addr[0] |= CONFIG_SYS_I2C_EEPROM_ADDR;
 288                addr_void[0]    |= CONFIG_SYS_I2C_EEPROM_ADDR;
 289#endif
 290                contr_reg[0] = 0xff;
 291                if (i2c_read (contr_r_addr[0], contr_r_addr[1], 1, contr_reg, 1) != 0) {
 292                        rcode = 1;
 293                }
 294                ctrl_reg_v = contr_reg[0];
 295
 296                /* Are any of the eeprom blocks write protected?
 297                 */
 298                if (ctrl_reg_v & 0x18) {
 299                        ctrl_reg_v &= ~0x18;   /* reset block protect bits  */
 300                        ctrl_reg_v |=  0x02;   /* set write enable latch    */
 301                        ctrl_reg_v &= ~0x04;   /* clear RWEL                */
 302
 303                        /* Set write enable latch.
 304                         */
 305                        contr_reg[0] = 0x02;
 306                        if (i2c_write (contr_r_addr[0], 0xff, 1, contr_reg, 1) != 0) {
 307                                rcode = 1;
 308                        }
 309
 310                        /* Set register write enable latch.
 311                         */
 312                        contr_reg[0] = 0x06;
 313                        if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) {
 314                                rcode = 1;
 315                        }
 316
 317                        /* Modify ctrl register.
 318                         */
 319                        contr_reg[0] = ctrl_reg_v;
 320                        if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) {
 321                                rcode = 1;
 322                        }
 323
 324                        /* The write (above) is an operation on NV memory.
 325                         * These can take some time (~5ms), and the device
 326                         * will not respond to further I2C messages till
 327                         * it's completed the write.
 328                         * So poll device for an I2C acknowledge.
 329                         * When we get one we know we can continue with other
 330                         * operations.
 331                         */
 332                        contr_reg[0] = 0;
 333                        for (i = 0; i < MAX_ACKNOWLEDGE_POLLS; i++) {
 334                                if (i2c_read (addr_void[0], addr_void[1], 1, contr_reg, 1) == 0)
 335                                        break;  /* got ack */
 336#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS)
 337                                udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
 338#endif
 339                        }
 340                        if (i == MAX_ACKNOWLEDGE_POLLS) {
 341                                puts ("EEPROM poll acknowledge failed\n");
 342                                rcode = 1;
 343                        }
 344                }
 345
 346                /* Is the write enable latch on?.
 347                 */
 348                else if (!(ctrl_reg_v & 0x02)) {
 349                        /* Set write enable latch.
 350                         */
 351                        contr_reg[0] = 0x02;
 352                        if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) {
 353                               rcode = 1;
 354                        }
 355                }
 356                /* Write is enabled ... now write eeprom value.
 357                 */
 358#endif
 359                if (i2c_write (addr[0], offset, alen-1, buffer, len) != 0)
 360                        rcode = 1;
 361
 362#endif
 363                buffer += len;
 364                offset += len;
 365
 366#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS)
 367                udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
 368#endif
 369        }
 370#if defined(CONFIG_SYS_EEPROM_WREN)
 371        eeprom_write_enable (dev_addr,0);
 372#endif
 373        return rcode;
 374}
 375
 376#if !defined(CONFIG_SPI) || defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
 377int
 378eeprom_probe (unsigned dev_addr, unsigned offset)
 379{
 380        unsigned char chip;
 381
 382        /* Probe the chip address
 383         */
 384#if CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
 385        chip = offset >> 8;             /* block number */
 386#else
 387        chip = offset >> 16;            /* block number */
 388#endif  /* CONFIG_SYS_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */
 389
 390        chip |= dev_addr;               /* insert device address */
 391
 392        return (i2c_probe (chip));
 393}
 394#endif
 395
 396/*-----------------------------------------------------------------------
 397 * Set default values
 398 */
 399#ifndef CONFIG_SYS_I2C_SPEED
 400#define CONFIG_SYS_I2C_SPEED    50000
 401#endif
 402
 403void eeprom_init  (void)
 404{
 405
 406#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
 407        spi_init_f ();
 408#endif
 409#if defined(CONFIG_HARD_I2C) || \
 410    defined(CONFIG_SOFT_I2C)
 411        i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 412#endif
 413}
 414
 415/*-----------------------------------------------------------------------
 416 */
 417
 418/***************************************************/
 419
 420#if defined(CONFIG_CMD_EEPROM)
 421
 422#ifdef CONFIG_SYS_I2C_MULTI_EEPROMS
 423U_BOOT_CMD(
 424        eeprom, 6,      1,      do_eeprom,
 425        "EEPROM sub-system",
 426        "read  devaddr addr off cnt\n"
 427        "eeprom write devaddr addr off cnt\n"
 428        "       - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'"
 429);
 430#else /* One EEPROM */
 431U_BOOT_CMD(
 432        eeprom, 5,      1,      do_eeprom,
 433        "EEPROM sub-system",
 434        "read  addr off cnt\n"
 435        "eeprom write addr off cnt\n"
 436        "       - read/write `cnt' bytes at EEPROM offset `off'"
 437);
 438#endif /* CONFIG_SYS_I2C_MULTI_EEPROMS */
 439
 440#endif
 441