#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 0
#endif
+#ifndef CONFIG_SYS_EEPROM_PAGE_WRITE_BITS
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 8
+#endif
+
+#define EEPROM_PAGE_SIZE (1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)
+#define EEPROM_PAGE_OFFSET(x) ((x) & (EEPROM_PAGE_SIZE - 1))
+
/*
* for CONFIG_SYS_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is
* 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
*/
#if !defined(CONFIG_SPI) || defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
#if !defined(CONFIG_SYS_I2C_EEPROM_ADDR_LEN) || \
- (CONFIG_SYS_I2C_EEPROM_ADDR_LEN < 1) || \
- (CONFIG_SYS_I2C_EEPROM_ADDR_LEN > 2)
+ (CONFIG_SYS_I2C_EEPROM_ADDR_LEN < 1) || \
+ (CONFIG_SYS_I2C_EEPROM_ADDR_LEN > 2)
#error CONFIG_SYS_I2C_EEPROM_ADDR_LEN must be 1 or 2
#endif
#endif
return 0;
}
-void eeprom_init(void)
+void eeprom_init(int bus)
{
/* SPI EEPROM */
#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
/* I2C EEPROM */
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C_SOFT)
+#if defined(CONFIG_SYS_I2C)
+ if (bus >= 0)
+ i2c_set_bus_num(bus);
+#endif
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
}
return alen;
}
+static int eeprom_len(unsigned offset, unsigned end)
+{
+ unsigned 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(CONFIG_SYS_I2C_FRAM)
+ unsigned blk_off = offset & 0xff;
+ unsigned maxlen = EEPROM_PAGE_SIZE - EEPROM_PAGE_OFFSET(blk_off);
+
+ if (maxlen > I2C_RXTX_LEN)
+ maxlen = I2C_RXTX_LEN;
+
+ if (len > maxlen)
+ len = maxlen;
+#endif
+
+ return len;
+}
+
static int eeprom_rw_block(unsigned offset, uchar *addr, unsigned alen,
uchar *buffer, unsigned len, bool read)
{
return ret;
}
-int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt)
+static int eeprom_rw(unsigned dev_addr, unsigned offset, uchar *buffer,
+ unsigned cnt, bool read)
{
unsigned end = offset + cnt;
- unsigned blk_off;
+ unsigned alen, len;
int rcode = 0;
uchar addr[3];
- /*
- * Read data until done or would cross a page boundary.
- * We must write the address again when changing pages
- * because the next page may be in a different device.
- */
while (offset < end) {
- unsigned alen, len;
-#if !defined(CONFIG_SYS_I2C_FRAM)
- unsigned maxlen;
-#endif
-
- blk_off = offset & 0xFF; /* block offset */
alen = eeprom_addr(dev_addr, offset, addr);
- 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(CONFIG_SYS_I2C_FRAM)
- maxlen = 0x100 - blk_off;
- if (maxlen > I2C_RXTX_LEN)
- maxlen = I2C_RXTX_LEN;
- if (len > maxlen)
- len = maxlen;
-#endif
+ len = eeprom_len(offset, end);
- rcode = eeprom_rw_block(offset, addr, alen, buffer, len, 1);
+ rcode = eeprom_rw_block(offset, addr, alen, buffer, len, read);
buffer += len;
offset += len;
+
+ if (!read)
+ udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
}
return rcode;
}
-int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt)
+int eeprom_read(unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt)
{
- unsigned end = offset + cnt;
- unsigned blk_off;
- int rcode = 0;
- uchar addr[3];
+ /*
+ * Read data until done or would cross a page boundary.
+ * We must write the address again when changing pages
+ * because the next page may be in a different device.
+ */
+ return eeprom_rw(dev_addr, offset, buffer, cnt, 1);
+}
+
+int eeprom_write(unsigned dev_addr, unsigned offset,
+ uchar *buffer, unsigned cnt)
+{
+ int ret;
eeprom_write_enable(dev_addr, 1);
* We must write the address again when changing pages
* because the address counter only increments within a page.
*/
-
- while (offset < end) {
- unsigned alen, len;
-#if !defined(CONFIG_SYS_I2C_FRAM)
- unsigned maxlen;
-#endif
-
- blk_off = offset & 0xFF; /* block offset */
- alen = eeprom_addr(dev_addr, offset, addr);
-
- len = end - offset;
-
- /*
- * For a FRAM device there is no limit on the number of the
- * bytes that can be accessed with the single read or write
- * operation.
- */
-#if !defined(CONFIG_SYS_I2C_FRAM)
-
-#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)
-
-#define EEPROM_PAGE_SIZE (1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)
-#define EEPROM_PAGE_OFFSET(x) ((x) & (EEPROM_PAGE_SIZE - 1))
-
- maxlen = EEPROM_PAGE_SIZE - EEPROM_PAGE_OFFSET(blk_off);
-#else
- maxlen = 0x100 - blk_off;
-#endif
- if (maxlen > I2C_RXTX_LEN)
- maxlen = I2C_RXTX_LEN;
-
- if (len > maxlen)
- len = maxlen;
-#endif
-
- rcode = eeprom_rw_block(offset, addr, alen, buffer, len, 0);
-
- buffer += len;
- offset += len;
-
- udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
- }
+ ret = eeprom_rw(dev_addr, offset, buffer, cnt, 0);
eeprom_write_enable(dev_addr, 0);
-
- return rcode;
+ return ret;
}
static int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char * const *args = &argv[2];
int rcode;
ulong dev_addr, addr, off, cnt;
+ int bus_addr;
switch (argc) {
#ifdef CONFIG_SYS_DEF_EEPROM_ADDR
case 5:
+ bus_addr = -1;
dev_addr = CONFIG_SYS_DEF_EEPROM_ADDR;
break;
#endif
case 6:
+ bus_addr = -1;
+ dev_addr = simple_strtoul(*args++, NULL, 16);
+ break;
+ case 7:
+ bus_addr = simple_strtoul(*args++, NULL, 16);
dev_addr = simple_strtoul(*args++, NULL, 16);
break;
default:
off = simple_strtoul(*args++, NULL, 16);
cnt = simple_strtoul(*args++, NULL, 16);
- eeprom_init();
+ eeprom_init(bus_addr);
- if (strcmp (argv[1], "read") == 0) {
+ if (strcmp(argv[1], "read") == 0) {
printf(fmt, dev_addr, argv[1], addr, off, cnt);
- rcode = eeprom_read(dev_addr, off, (uchar *) addr, cnt);
+ rcode = eeprom_read(dev_addr, off, (uchar *)addr, cnt);
- puts ("done\n");
+ puts("done\n");
return rcode;
- } else if (strcmp (argv[1], "write") == 0) {
+ } else if (strcmp(argv[1], "write") == 0) {
printf(fmt, dev_addr, argv[1], addr, off, cnt);
- rcode = eeprom_write(dev_addr, off, (uchar *) addr, cnt);
+ rcode = eeprom_write(dev_addr, off, (uchar *)addr, cnt);
- puts ("done\n");
+ puts("done\n");
return rcode;
}
}
U_BOOT_CMD(
- eeprom, 6, 1, do_eeprom,
+ eeprom, 7, 1, do_eeprom,
"EEPROM sub-system",
- "read devaddr addr off cnt\n"
- "eeprom write devaddr addr off cnt\n"
+ "read <bus> <devaddr> addr off cnt\n"
+ "eeprom write <bus> <devaddr> addr off cnt\n"
" - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'"
)