*
*/
+/*
+ * Support for read and write access to EEPROM like memory devices. This
+ * includes regular EEPROM as well as FRAM (ferroelectic nonvolaile RAM).
+ * FRAM devices read and write data at bus speed. In particular, there is no
+ * write delay. Also, there is no limit imposed on the numer of bytes that can
+ * be transferred with a single read or write.
+ *
+ * Use the following configuration options to ensure no unneeded performance
+ * degradation (typical for EEPROM) is incured for FRAM memory:
+ *
+ * #define CFG_I2C_FRAM
+ * #undef CFG_EEPROM_PAGE_WRITE_DELAY_MS
+ *
+ */
+
#include <common.h>
#include <config.h>
#include <command.h>
#include <i2c.h>
-#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM)
+#if defined(CFG_ENV_IS_IN_EEPROM) || defined(CONFIG_CMD_EEPROM)
extern void eeprom_init (void);
extern int eeprom_read (unsigned dev_addr, unsigned offset,
uchar *buffer, unsigned cnt);
extern int eeprom_write (unsigned dev_addr, unsigned offset,
uchar *buffer, unsigned cnt);
+#if defined(CFG_EEPROM_WREN)
+extern int eeprom_write_enable (unsigned dev_addr, int state);
+#endif
#endif
/* ------------------------------------------------------------------------- */
-#if (CONFIG_COMMANDS & CFG_CMD_EEPROM)
+#if defined(CONFIG_CMD_EEPROM)
int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
const char *const fmt =
rcode = eeprom_read (dev_addr, off, (uchar *) addr, cnt);
- printf ("done\n");
+ puts ("done\n");
return rcode;
} else if (strcmp (argv[1], "write") == 0) {
int rcode;
rcode = eeprom_write (dev_addr, off, (uchar *) addr, cnt);
- printf ("done\n");
+ puts ("done\n");
return rcode;
}
}
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
-#endif /* CFG_CMD_EEPROM */
+#endif
/*-----------------------------------------------------------------------
*
* 0x00000nxx for EEPROM address selectors and page number at n.
*/
-#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM)
+#if defined(CFG_ENV_IS_IN_EEPROM) || defined(CONFIG_CMD_EEPROM)
#ifndef CONFIG_SPI
#if !defined(CFG_I2C_EEPROM_ADDR_LEN) || CFG_I2C_EEPROM_ADDR_LEN < 1 || CFG_I2C_EEPROM_ADDR_LEN > 2
* because the next page may be in a different device.
*/
while (offset < end) {
- unsigned alen, len, maxlen;
+ unsigned alen, len;
+#if !defined(CFG_I2C_FRAM)
+ unsigned maxlen;
+#endif
+
#if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
uchar addr[2];
addr[0] |= dev_addr; /* insert device address */
+ len = end - offset;
+
+ /*
+ * For a FRAM device there is no limit on the number of the
+ * bytes that can be ccessed with the single read or write
+ * operation.
+ */
+#if !defined(CFG_I2C_FRAM)
maxlen = 0x100 - blk_off;
if (maxlen > I2C_RXTX_LEN)
maxlen = I2C_RXTX_LEN;
- len = end - offset;
if (len > maxlen)
len = maxlen;
+#endif
+
#ifdef CONFIG_SPI
spi_read (addr, alen, buffer, len);
#else
buffer += len;
offset += len;
}
+
return rcode;
}
int i;
#endif
+#if defined(CFG_EEPROM_WREN)
+ eeprom_write_enable (dev_addr,1);
+#endif
/* Write data until done or would cross a write page boundary.
* We must write the address again when changing pages
* because the address counter only increments within a page.
*/
while (offset < end) {
- unsigned alen, len, maxlen;
+ unsigned alen, len;
+#if !defined(CFG_I2C_FRAM)
+ unsigned maxlen;
+#endif
+
#if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
uchar addr[2];
addr[0] |= dev_addr; /* insert device address */
+ len = end - offset;
+
+ /*
+ * For a FRAM device there is no limit on the number of the
+ * bytes that can be ccessed with the single read or write
+ * operation.
+ */
+#if !defined(CFG_I2C_FRAM)
+
#if defined(CFG_EEPROM_PAGE_WRITE_BITS)
#define EEPROM_PAGE_SIZE (1 << CFG_EEPROM_PAGE_WRITE_BITS)
if (maxlen > I2C_RXTX_LEN)
maxlen = I2C_RXTX_LEN;
- len = end - offset;
if (len > maxlen)
len = maxlen;
+#endif
+
#ifdef CONFIG_SPI
spi_write (addr, alen, buffer, len);
#else
#endif
}
if (i == MAX_ACKNOWLEDGE_POLLS) {
- printf("EEPROM poll acknowledge failed\n");
+ puts ("EEPROM poll acknowledge failed\n");
rcode = 1;
}
}
udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
#endif
}
+#if defined(CFG_EEPROM_WREN)
+ eeprom_write_enable (dev_addr,0);
+#endif
return rcode;
}
}
/*-----------------------------------------------------------------------
*/
-#endif /* CFG_CMD_EEPROM */
+#endif
+
/***************************************************/
-#if (CONFIG_COMMANDS & CFG_CMD_EEPROM)
+#if defined(CONFIG_CMD_EEPROM)
#ifdef CFG_I2C_MULTI_EEPROMS
U_BOOT_CMD(
);
#endif /* CFG_I2C_MULTI_EEPROMS */
-#endif /* CFG_CMD_EEPROM */
+#endif