cmd_eeprom.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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. #include <common.h>
  25. #include <config.h>
  26. #include <command.h>
  27. #include <i2c.h>
  28. #if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM)
  29. extern void eeprom_init (void);
  30. extern int eeprom_read (unsigned dev_addr, unsigned offset,
  31. uchar *buffer, unsigned cnt);
  32. extern int eeprom_write (unsigned dev_addr, unsigned offset,
  33. uchar *buffer, unsigned cnt);
  34. #endif
  35. #if defined(CFG_EEPROM_X40430)
  36. /* Maximum number of times to poll for acknowledge after write */
  37. #define MAX_ACKNOWLEDGE_POLLS 10
  38. #endif
  39. /* ------------------------------------------------------------------------- */
  40. #if (CONFIG_COMMANDS & CFG_CMD_EEPROM)
  41. int do_eeprom ( cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
  42. {
  43. const char *const fmt =
  44. "\nEEPROM @0x%lX %s: addr %08lx off %04lx count %ld ... ";
  45. #if defined(CFG_I2C_MULTI_EEPROMS)
  46. if (argc == 6) {
  47. ulong dev_addr = simple_strtoul (argv[2], NULL, 16);
  48. ulong addr = simple_strtoul (argv[3], NULL, 16);
  49. ulong off = simple_strtoul (argv[4], NULL, 16);
  50. ulong cnt = simple_strtoul (argv[5], NULL, 16);
  51. #else
  52. if (argc == 5) {
  53. ulong dev_addr = CFG_DEF_EEPROM_ADDR;
  54. ulong addr = simple_strtoul (argv[2], NULL, 16);
  55. ulong off = simple_strtoul (argv[3], NULL, 16);
  56. ulong cnt = simple_strtoul (argv[4], NULL, 16);
  57. #endif /* CFG_I2C_MULTI_EEPROMS */
  58. # ifndef CONFIG_SPI
  59. eeprom_init ();
  60. # endif /* !CONFIG_SPI */
  61. if (strcmp (argv[1], "read") == 0) {
  62. int rcode;
  63. printf (fmt, dev_addr, argv[1], addr, off, cnt);
  64. rcode = eeprom_read (dev_addr, off, (uchar *) addr, cnt);
  65. printf ("done\n");
  66. return rcode;
  67. } else if (strcmp (argv[1], "write") == 0) {
  68. int rcode;
  69. printf (fmt, dev_addr, argv[1], addr, off, cnt);
  70. rcode = eeprom_write (dev_addr, off, (uchar *) addr, cnt);
  71. printf ("done\n");
  72. return rcode;
  73. }
  74. }
  75. printf ("Usage:\n%s\n", cmdtp->usage);
  76. return 1;
  77. }
  78. #endif /* CFG_CMD_EEPROM */
  79. /*-----------------------------------------------------------------------
  80. *
  81. * for CFG_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is
  82. * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
  83. *
  84. * for CFG_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is
  85. * 0x00000nxx for EEPROM address selectors and page number at n.
  86. */
  87. #if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM)
  88. #ifndef CONFIG_SPI
  89. #if !defined(CFG_I2C_EEPROM_ADDR_LEN) || CFG_I2C_EEPROM_ADDR_LEN < 1 || CFG_I2C_EEPROM_ADDR_LEN > 2
  90. #error CFG_I2C_EEPROM_ADDR_LEN must be 1 or 2
  91. #endif
  92. #endif
  93. int eeprom_read (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt)
  94. {
  95. unsigned end = offset + cnt;
  96. unsigned blk_off;
  97. int rcode = 0;
  98. /* Read data until done or would cross a page boundary.
  99. * We must write the address again when changing pages
  100. * because the next page may be in a different device.
  101. */
  102. while (offset < end) {
  103. unsigned alen, len, maxlen;
  104. #if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
  105. uchar addr[2];
  106. blk_off = offset & 0xFF; /* block offset */
  107. addr[0] = offset >> 8; /* block number */
  108. addr[1] = blk_off; /* block offset */
  109. alen = 2;
  110. #else
  111. uchar addr[3];
  112. blk_off = offset & 0xFF; /* block offset */
  113. addr[0] = offset >> 16; /* block number */
  114. addr[1] = offset >> 8; /* upper address octet */
  115. addr[2] = blk_off; /* lower address octet */
  116. alen = 3;
  117. #endif /* CFG_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */
  118. addr[0] |= dev_addr; /* insert device address */
  119. maxlen = 0x100 - blk_off;
  120. if (maxlen > I2C_RXTX_LEN)
  121. maxlen = I2C_RXTX_LEN;
  122. len = end - offset;
  123. if (len > maxlen)
  124. len = maxlen;
  125. #ifdef CONFIG_SPI
  126. spi_read (addr, alen, buffer, len);
  127. #else
  128. if (i2c_read (addr[0], offset, alen-1, buffer, len) != 0)
  129. rcode = 1;
  130. #endif
  131. buffer += len;
  132. offset += len;
  133. }
  134. return rcode;
  135. }
  136. /*-----------------------------------------------------------------------
  137. *
  138. * for CFG_I2C_EEPROM_ADDR_LEN == 2 (16-bit EEPROM address) offset is
  139. * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
  140. *
  141. * for CFG_I2C_EEPROM_ADDR_LEN == 1 (8-bit EEPROM page address) offset is
  142. * 0x00000nxx for EEPROM address selectors and page number at n.
  143. */
  144. int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt)
  145. {
  146. unsigned end = offset + cnt;
  147. unsigned blk_off;
  148. int rcode = 0;
  149. #if defined(CFG_EEPROM_X40430)
  150. uchar contr_r_addr[2];
  151. uchar addr_void[2];
  152. uchar contr_reg[2];
  153. uchar ctrl_reg_v;
  154. int i;
  155. #endif
  156. /* Write data until done or would cross a write page boundary.
  157. * We must write the address again when changing pages
  158. * because the address counter only increments within a page.
  159. */
  160. while (offset < end) {
  161. unsigned alen, len, maxlen;
  162. #if CFG_I2C_EEPROM_ADDR_LEN == 1 && !defined(CONFIG_SPI_X)
  163. uchar addr[2];
  164. blk_off = offset & 0xFF; /* block offset */
  165. addr[0] = offset >> 8; /* block number */
  166. addr[1] = blk_off; /* block offset */
  167. alen = 2;
  168. #else
  169. uchar addr[3];
  170. blk_off = offset & 0xFF; /* block offset */
  171. addr[0] = offset >> 16; /* block number */
  172. addr[1] = offset >> 8; /* upper address octet */
  173. addr[2] = blk_off; /* lower address octet */
  174. alen = 3;
  175. #endif /* CFG_I2C_EEPROM_ADDR_LEN, CONFIG_SPI_X */
  176. addr[0] |= dev_addr; /* insert device address */
  177. #if defined(CFG_EEPROM_PAGE_WRITE_BITS)
  178. #define EEPROM_PAGE_SIZE (1 << CFG_EEPROM_PAGE_WRITE_BITS)
  179. #define EEPROM_PAGE_OFFSET(x) ((x) & (EEPROM_PAGE_SIZE - 1))
  180. maxlen = EEPROM_PAGE_SIZE - EEPROM_PAGE_OFFSET(blk_off);
  181. #else
  182. maxlen = 0x100 - blk_off;
  183. #endif
  184. if (maxlen > I2C_RXTX_LEN)
  185. maxlen = I2C_RXTX_LEN;
  186. len = end - offset;
  187. if (len > maxlen)
  188. len = maxlen;
  189. #ifdef CONFIG_SPI
  190. spi_write (addr, alen, buffer, len);
  191. #else
  192. #if defined(CFG_EEPROM_X40430)
  193. /* Get the value of the control register.
  194. * Set current address (internal pointer in the x40430)
  195. * to 0x1ff.
  196. */
  197. contr_r_addr[0] = 9;
  198. contr_r_addr[1] = 0xff;
  199. addr_void[0] = 0;
  200. addr_void[1] = addr[1];
  201. #ifdef CFG_I2C_EEPROM_ADDR
  202. contr_r_addr[0] |= CFG_I2C_EEPROM_ADDR;
  203. addr_void[0] |= CFG_I2C_EEPROM_ADDR;
  204. #endif
  205. contr_reg[0] = 0xff;
  206. if (i2c_read (contr_r_addr[0], contr_r_addr[1], 1, contr_reg, 1) != 0) {
  207. rcode = 1;
  208. }
  209. ctrl_reg_v = contr_reg[0];
  210. /* Are any of the eeprom blocks write protected?
  211. */
  212. if (ctrl_reg_v & 0x18) {
  213. ctrl_reg_v &= ~0x18; /* reset block protect bits */
  214. ctrl_reg_v |= 0x02; /* set write enable latch */
  215. ctrl_reg_v &= ~0x04; /* clear RWEL */
  216. /* Set write enable latch.
  217. */
  218. contr_reg[0] = 0x02;
  219. if (i2c_write (contr_r_addr[0], 0xff, 1, contr_reg, 1) != 0) {
  220. rcode = 1;
  221. }
  222. /* Set register write enable latch.
  223. */
  224. contr_reg[0] = 0x06;
  225. if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) {
  226. rcode = 1;
  227. }
  228. /* Modify ctrl register.
  229. */
  230. contr_reg[0] = ctrl_reg_v;
  231. if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) {
  232. rcode = 1;
  233. }
  234. /* The write (above) is an operation on NV memory.
  235. * These can take some time (~5ms), and the device
  236. * will not respond to further I2C messages till
  237. * it's completed the write.
  238. * So poll device for an I2C acknowledge.
  239. * When we get one we know we can continue with other
  240. * operations.
  241. */
  242. contr_reg[0] = 0;
  243. for (i = 0; i < MAX_ACKNOWLEDGE_POLLS; i++) {
  244. if (i2c_read (addr_void[0], addr_void[1], 1, contr_reg, 1) == 1)
  245. break; /* got ack */
  246. #if defined(CFG_EEPROM_PAGE_WRITE_DELAY_MS)
  247. udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
  248. #endif
  249. }
  250. if (i == MAX_ACKNOWLEDGE_POLLS) {
  251. printf("EEPROM poll acknowledge failed\n");
  252. rcode = 1;
  253. }
  254. }
  255. /* Is the write enable latch on?.
  256. */
  257. else if (!(ctrl_reg_v & 0x02)) {
  258. /* Set write enable latch.
  259. */
  260. contr_reg[0] = 0x02;
  261. if (i2c_write (contr_r_addr[0], 0xFF, 1, contr_reg, 1) != 0) {
  262. rcode = 1;
  263. }
  264. }
  265. /* Write is enabled ... now write eeprom value.
  266. */
  267. #endif
  268. if (i2c_write (addr[0], offset, alen-1, buffer, len) != 0)
  269. rcode = 1;
  270. #endif
  271. buffer += len;
  272. offset += len;
  273. #if defined(CFG_EEPROM_PAGE_WRITE_DELAY_MS)
  274. udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
  275. #endif
  276. }
  277. return rcode;
  278. }
  279. /*-----------------------------------------------------------------------
  280. * Set default values
  281. */
  282. #ifndef CFG_I2C_SPEED
  283. #define CFG_I2C_SPEED 50000
  284. #endif
  285. #ifndef CFG_I2C_SLAVE
  286. #define CFG_I2C_SLAVE 0xFE
  287. #endif
  288. void eeprom_init (void)
  289. {
  290. #if defined(CONFIG_SPI)
  291. spi_init_f ();
  292. #endif
  293. #if defined(CONFIG_HARD_I2C) || \
  294. defined(CONFIG_SOFT_I2C)
  295. i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
  296. #endif
  297. }
  298. /*-----------------------------------------------------------------------
  299. */
  300. #endif /* CFG_CMD_EEPROM */